优化脚本,增强兼容性

This commit is contained in:
Ing 2025-03-06 17:02:25 +08:00
parent 11a5f4dd7c
commit 7c0e5ba3e3
20 changed files with 533 additions and 395 deletions

View File

@ -47,7 +47,7 @@ jobs:
if [ "${PRERELEASE}" = "true" ]; then
TAG="$(curl -skL --connect-timeout 10 "${REPO}/tags" | grep "/refs/tags/.*\.zip" | sed -E 's/.*\/refs\/tags\/(.*)\.zip.*$/\1/' | sort -rV | head -1)"
else
TAG="$(curl -skL --connect-timeout 10 -w %{url_effective} -o /dev/null "${REPO}/releases/latest" | awk -F'/' '{print $NF}')"
TAG="$(curl -skL --connect-timeout 10 -w "%{url_effective}" -o /dev/null "${REPO}/releases/latest" | awk -F'/' '{print $NF}')"
fi
[ "${TAG:0:1}" = "v" ] && TAG="${TAG:1}"
rm -f rr-${TAG}.img.zip

View File

@ -159,20 +159,23 @@ jobs:
}
function readConfigKey() {
local result=$(sudo yq eval ".${1} | explode(.)" "${2}" 2>/dev/null)
local result
result=$(sudo yq eval ".${1} | explode(.)" "${2}" 2>/dev/null)
[ "${result}" = "null" ] && echo "" || echo "${result}"
}
function mergeConfigModules() {
# Error: bad file '-': cannot index array with '8139cp' (strconv.ParseInt: parsing "8139cp": invalid syntax)
# When the first key is a pure number, yq will not process it as a string by default. The current solution is to insert a placeholder key.
local MS="RRORG\n${1// /\\n}"
local L="$(echo -en "${MS}" | awk '{print "modules."$1":"}')"
local xmlfile=$(mktemp)
echo -en "${L}" | sudo yq -p p -o y >"${xmlfile}"
deleteConfigKey "modules.\"RRORG\"" "${xmlfile}"
sudo yq eval-all --inplace '. as $item ireduce ({}; . * $item)' --inplace "${2}" "${xmlfile}" 2>/dev/null
rm -f "${xmlfile}"
local MS ML XF
MS="RRORG\n${1// /\\n}"
ML="$(echo -en "${MS}" | awk '{print "modules."$1":"}')"
XF=$(mktemp 2>/dev/null)
XF=${XF:-/tmp/tmp.XXXXXXXXXX}
echo -en "${ML}" | sudo yq -p p -o y >"${XF}"
deleteConfigKey "modules.\"RRORG\"" "${XF}"
sudo yq eval-all --inplace '. as $item ireduce ({}; . * $item)' --inplace "${2}" "${XF}" 2>/dev/null
rm -f "${XF}"
}
REPO="${{ github.server_url }}/${{ github.repository }}"
@ -184,7 +187,7 @@ jobs:
if [ "${PRERELEASE}" = "true" ]; then
TAG="$(curl -skL --connect-timeout 10 "${REPO}/tags" | grep "/refs/tags/.*\.zip" | sed -E 's/.*\/refs\/tags\/(.*)\.zip.*$/\1/' | sort -rV | head -1)"
else
TAG="$(curl -skL --connect-timeout 10 -w %{url_effective} -o /dev/null "${REPO}/releases/latest" | awk -F'/' '{print $NF}')"
TAG="$(curl -skL --connect-timeout 10 -w "%{url_effective}" -o /dev/null "${REPO}/releases/latest" | awk -F'/' '{print $NF}')"
fi
[ "${TAG:0:1}" = "v" ] && TAG="${TAG:1}"
rm -f rr-${TAG}.img.zip
@ -283,33 +286,33 @@ jobs:
if [ "${{ env.format }}" = "ova" ]; then
. scripts/func.sh "${{ secrets.RRORG }}"
convertova "rr/rr.img" "rr/rr.ova"
(cd rr; sha256sum rr.ova >../sha256sum)
(cd rr && sha256sum rr.ova >../sha256sum)
zip -9 "rr-${MODEL}-${TAG}-${{ github.run_id }}.ova.zip" -j rr/rr.ova ${USER_CONFIG_FILE} sha256sum README.txt
elif [ "${{ env.format }}" = "vmx" ]; then
. scripts/func.sh "${{ secrets.RRORG }}"
convertvmx "rr/rr.img" "rr.vmx" # rr.vmx is a directory
(cd rr.vmx; sha256sum * >../sha256sum)
(cd rr.vmx && sha256sum * >../sha256sum)
zip -9 "rr-${MODEL}-${TAG}-${{ github.run_id }}.vmx.zip" -r rr.vmx ${USER_CONFIG_FILE} sha256sum README.txt
elif [ "${{ env.format }}" = "vmdk" ]; then
qemu-img convert rr/rr.img -O vmdk -o 'adapter_type=lsilogic,subformat=streamOptimized,compat6' rr/rr.vmdk
(cd rr; sha256sum rr.vmdk >../sha256sum)
(cd rr && sha256sum rr.vmdk >../sha256sum)
zip -9 "rr-${MODEL}-${TAG}-${{ github.run_id }}.vmdk.zip" -j rr/rr.vmdk ${USER_CONFIG_FILE} sha256sum README.txt
elif [ "${{ env.format }}" = "flat" ]; then
qemu-img convert rr/rr.img -O vmdk -o 'adapter_type=lsilogic,subformat=monolithicFlat,compat6' rr/rr.vmdk
(cd rr; sha256sum rr*.vmdk >../sha256sum)
(cd rr && sha256sum rr*.vmdk >../sha256sum)
zip -9 "rr-${MODEL}-${TAG}-${{ github.run_id }}.flat.zip" -j rr/rr*.vmdk ${USER_CONFIG_FILE} sha256sum README.txt
elif [ "${{ env.format }}" = "vhd" ]; then
. scripts/func.sh "${{ secrets.RRORG }}"
qemu-img convert rr/rr.img -O vpc rr/rr.vhd
createvmc "rr/rr.vhd" "rr/rr.vmc"
(cd rr; sha256sum rr.vhd >../sha256sum)
(cd rr && sha256sum rr.vhd >../sha256sum)
zip -9 "rr-${MODEL}-${TAG}-${{ github.run_id }}.vhd.zip" -j rr/rr.vmc rr/rr.vhd ${USER_CONFIG_FILE} sha256sum README.txt
elif [ "${{ env.format }}" = "vhdx" ]; then
qemu-img convert rr/rr.img -O vhdx -o subformat=dynamic rr/rr.vhdx
(cd rr; sha256sum rr.vhdx >../sha256sum)
(cd rr && sha256sum rr.vhdx >../sha256sum)
zip -9 "rr-${MODEL}-${TAG}-${{ github.run_id }}.vhdx.zip" -j rr/rr.vhdx ${USER_CONFIG_FILE} sha256sum README.txt
else
(cd rr; sha256sum rr.img >../sha256sum)
(cd rr && sha256sum rr.img >../sha256sum)
zip -9 "rr-${MODEL}-${TAG}-${{ github.run_id }}.img.zip" -j rr/rr.img ${USER_CONFIG_FILE} sha256sum README.txt
fi

View File

@ -1,4 +1,12 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
# shellcheck disable=SC2034
set -e
[ -z "${WORK_PATH}" ] || [ ! -d "${WORK_PATH}/include" ] && WORK_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
@ -114,7 +122,7 @@ if ! readConfigMap "addons" "${USER_CONFIG_FILE}" | grep -q nvmesystem; then
[ ${HASATA} = "0" ] && printf "\033[1;33m*** %s ***\033[0m\n" "$(TEXT "Notice: Please insert at least one sata/scsi disk for system installation (except for the bootloader disk).")"
fi
if checkBIOS_VT_d && [ $(echo "${KVER:-4}" | cut -d'.' -f1) -lt 5 ]; then
if checkBIOS_VT_d && [ "$(echo "${KVER:-4}" | cut -d'.' -f1)" -lt 5 ]; then
printf "\033[1;33m*** %s ***\033[0m\n" "$(TEXT "Notice: Please disable Intel(VT-d)/AMD(AMD-Vi) in BIOS/UEFI settings if you encounter a boot failure.")"
fi
@ -158,10 +166,10 @@ if [ ${EFI} -eq 1 ]; then
else
CMDLINE['noefi']=""
fi
if [ $(echo "${KVER:-4}" | cut -d'.' -f1) -lt 5 ]; then
if [ "$(echo "${KVER:-4}" | cut -d'.' -f1)" -lt 5 ]; then
if [ ! "${BUS}" = "usb" ]; then
SZ=$(blockdev --getsz ${LOADER_DISK} 2>/dev/null) # SZ=$(cat /sys/block/${LOADER_DISK/\/dev\//}/size)
SS=$(blockdev --getss ${LOADER_DISK} 2>/dev/null) # SS=$(cat /sys/block/${LOADER_DISK/\/dev\//}/queue/hw_sector_size)
SZ=$(blockdev --getsz "${LOADER_DISK}" 2>/dev/null) # SZ=$(cat /sys/block/${LOADER_DISK/\/dev\//}/size)
SS=$(blockdev --getss "${LOADER_DISK}" 2>/dev/null) # SS=$(cat /sys/block/${LOADER_DISK/\/dev\//}/queue/hw_sector_size)
SIZE=$((${SZ:-0} * ${SS:-0} / 1024 / 1024 + 10))
# Read SATADoM type
SATADOM="$(readConfigKey "satadom" "${USER_CONFIG_FILE}")"
@ -250,8 +258,8 @@ if echo "purley broadwellnkv2" | grep -wq "${PLATFORM}"; then
CMDLINE["SASmodel"]="1"
fi
SSID="$(cat ${PART1_PATH}/wpa_supplicant.conf 2>/dev/null | grep 'ssid=' | cut -d'=' -f2 | sed 's/^"//; s/"$//' | xxd -p | tr -d '\n')"
PSK="$(cat ${PART1_PATH}/wpa_supplicant.conf 2>/dev/null | grep 'psk=' | cut -d'=' -f2 | sed 's/^"//; s/"$//' | xxd -p | tr -d '\n')"
SSID="$(cat "${PART1_PATH}/wpa_supplicant.conf" 2>/dev/null | grep 'ssid=' | cut -d'=' -f2 | sed 's/^"//; s/"$//' | xxd -p | tr -d '\n')"
PSK="$(cat "${PART1_PATH}/wpa_supplicant.conf" 2>/dev/null | grep 'psk=' | cut -d'=' -f2 | sed 's/^"//; s/"$//' | xxd -p | tr -d '\n')"
if [ -n "${SSID}" ] && [ -n "${PSK}" ]; then
CMDLINE["wpa.ssid"]="${SSID}"
@ -260,11 +268,11 @@ fi
while IFS=': ' read -r KEY VALUE; do
[ -n "${KEY}" ] && CMDLINE["network.${KEY}"]="${VALUE}"
done <<<$(readConfigMap "network" "${USER_CONFIG_FILE}")
done <<<"$(readConfigMap "network" "${USER_CONFIG_FILE}")"
while IFS=': ' read -r KEY VALUE; do
[ -n "${KEY}" ] && CMDLINE["${KEY}"]="${VALUE}"
done <<<$(readConfigMap "cmdline" "${USER_CONFIG_FILE}")
done <<<"$(readConfigMap "cmdline" "${USER_CONFIG_FILE}")"
# Prepare command line
CMDLINE_LINE=""
@ -273,7 +281,7 @@ for KEY in "${!CMDLINE[@]}"; do
CMDLINE_LINE+=" ${KEY}"
[ -n "${VALUE}" ] && CMDLINE_LINE+="=${VALUE}"
done
CMDLINE_LINE=$(echo "${CMDLINE_LINE}" | sed 's/^ //') # Remove leading space
CMDLINE_LINE="$(echo "${CMDLINE_LINE}" | sed 's/^ //')" # Remove leading space
printf "%s:\n\033[1;36m%s\033[0m\n" "$(TEXT "Cmdline")" "${CMDLINE_LINE}"
# Check if user wants to modify at this stage
@ -334,7 +342,7 @@ else
rm -f ${USER_RSYSENVFILE} 2>/dev/null || true
grub-editenv ${USER_GRUBENVFILE} unset dsm_cmdline
grub-editenv ${USER_GRUBENVFILE} unset next_entry
ETHX=$(ls /sys/class/net/ 2>/dev/null | grep -v lo) || true
ETHX="$(find /sys/class/net/ -mindepth 1 -maxdepth 1 ! -name lo -exec basename {} \; | sort)"
printf "$(TEXT "Detected %s network cards.\n")" "$(echo "${ETHX}" | wc -w)"
printf "$(TEXT "Checking Connect.")"
COUNT=0
@ -343,7 +351,7 @@ else
while [ ${COUNT} -lt $((${BOOTIPWAIT} + 32)) ]; do
MSG=""
for N in ${ETHX}; do
if [ "1" = "$(cat /sys/class/net/${N}/carrier 2>/dev/null)" ]; then
if [ "1" = "$(cat "/sys/class/net/${N}/carrier" 2>/dev/null)" ]; then
MSG+="${N} "
fi
done
@ -361,19 +369,19 @@ else
printf "$(TEXT "Waiting IP.\n")"
for N in ${ETHX}; do
COUNT=0
DRIVER=$(ls -ld /sys/class/net/${N}/device/driver 2>/dev/null | awk -F '/' '{print $NF}')
MAC=$(cat /sys/class/net/${N}/address 2>/dev/null)
DRIVER="$(basename "$(realpath "/sys/class/net/${N}/device/driver" 2>/dev/null)" 2>/dev/null)"
MAC="$(cat "/sys/class/net/${N}/address" 2>/dev/null)"
printf "%s(%s): " "${N}" "${MAC}@${DRIVER}"
while true; do
if false && [ ! "${N::3}" = "eth" ]; then
printf "\r%s(%s): %s\n" "${N}" "${MAC}@${DRIVER}" "$(TEXT "IGNORE (Does not support non-wired network card.)")"
break
fi
if [ -z "$(cat /sys/class/net/${N}/carrier 2>/dev/null)" ]; then
if [ -z "$(cat "/sys/class/net/${N}/carrier" 2>/dev/null)" ]; then
printf "\r%s(%s): %s\n" "${N}" "${MAC}@${DRIVER}" "$(TEXT "DOWN")"
break
fi
if [ "0" = "$(cat /sys/class/net/${N}/carrier 2>/dev/null)" ]; then
if [ "0" = "$(cat "/sys/class/net/${N}/carrier" 2>/dev/null)" ]; then
printf "\r%s(%s): %s\n" "${N}" "${MAC}@${DRIVER}" "$(TEXT "NOT CONNECTED")"
break
fi
@ -405,16 +413,16 @@ else
IP="$(getIP)"
echo "${IP}" | grep -q "^169\.254\." && IP=""
[ -n "${IP}" ] && URL="http://${IP}:5000" || URL="http://find.synology.com/"
python3 ${WORK_PATH}/include/functions.py makeqr -d "${URL}" -l "6" -o "${TMP_PATH}/qrcode_boot.png"
python3 "${WORK_PATH}/include/functions.py" "makeqr" -d "${URL}" -l "6" -o "${TMP_PATH}/qrcode_boot.png"
[ -f "${TMP_PATH}/qrcode_boot.png" ] && echo | fbv -acufi "${TMP_PATH}/qrcode_boot.png" >/dev/null 2>/dev/null || true
python3 ${WORK_PATH}/include/functions.py makeqr -f "${WORK_PATH}/include/qhxg.png" -l "7" -o "${TMP_PATH}/qrcode_qhxg.png"
python3 "${WORK_PATH}/include/functions.py" "makeqr" -f "${WORK_PATH}/include/qhxg.png" -l "7" -o "${TMP_PATH}/qrcode_qhxg.png"
[ -f "${TMP_PATH}/qrcode_qhxg.png" ] && echo | fbv -acufi "${TMP_PATH}/qrcode_qhxg.png" >/dev/null 2>/dev/null || true
fi
# Executes DSM kernel via KEXEC
KEXECARGS="-a"
if [ $(echo "${KVER:-4}" | cut -d'.' -f1) -lt 4 ] && [ ${EFI} -eq 1 ]; then
if [ "$(echo "${KVER:-4}" | cut -d'.' -f1)" -lt 4 ] && [ ${EFI} -eq 1 ]; then
printf "\033[1;33m%s\033[0m\n" "$(TEXT "Warning, running kexec with --noefi param, strange things will happen!!")"
KEXECARGS+=" --noefi"
fi
@ -429,9 +437,9 @@ else
done
# Disconnect wireless
lsmod | grep -q iwlwifi && for N in $(ls /sys/class/net/ 2>/dev/null | grep wlan); do connectwlanif "${N}" 0 2>/dev/null; done
lsmod | grep -q iwlwifi && for F in /sys/class/net/wlan*; do [ ! -e "${F}" ] && continue; connectwlanif "$(basename "${F}")" 0 2>/dev/null; done
# Unload all network drivers
# for D in $(realpath /sys/class/net/*/device/driver); do rmmod -f "$(basename ${D})" 2>/dev/null || true; done
# for F in $(realpath /sys/class/net/*/device/driver); do [ ! -e "${F}" ] && continue; rmmod -f "$(basename ${F})" 2>/dev/null || true; done
# Unload all graphics drivers
# for D in $(lsmod | grep -E '^(nouveau|amdgpu|radeon|i915)' | awk '{print $1}'); do rmmod -f "${D}" 2>/dev/null || true; done

View File

@ -1,4 +1,10 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
read_u8() {
dd if="${1}" bs=1 skip="$((${2}))" count=1 2>/dev/null | od -An -tu1 | grep -Eo '[0-9]+'

View File

@ -1,5 +1,10 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
# Calculate the amount of space needed to run the kernel, including room for
# the .bss and .brk sections.
#
@ -14,7 +19,7 @@ if [ -z "${OUT}" ]; then
exit 1
fi
read -r sizeA offsetA sizeB offsetB <<<$(echo ${OUT} | awk '{printf "%d %d %d %d", strtonum($1), strtonum($2), strtonum($3), strtonum($4)}')
read -r sizeA offsetA sizeB offsetB <<<"$(echo ${OUT} | awk '{printf "%d %d %d %d", strtonum($1), strtonum($2), strtonum($3), strtonum($4)}')"
runSize=$((offsetA + sizeA + sizeB))

View File

@ -1,3 +1,13 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
# shellcheck disable=SC2115,SC2155
###############################################################################
# Return list of available addons
# 1 - Platform
@ -19,7 +29,7 @@ function availableAddons() {
[ -z "${DESC}" ] && DESC="$(readConfigKey "description.en_US" "${D}/manifest.yml")"
[ -z "${DESC}" ] && DESC="$(readConfigKey "description" "${D}/manifest.yml")"
echo -e "${ADDON}\t${DESC:-"unknown"}"
done <<<$(find "${ADDONS_PATH}" -maxdepth 1 -type d 2>/dev/null | sort)
done <<<"$(find "${ADDONS_PATH}" -maxdepth 1 -type d 2>/dev/null | sort)"
}
###############################################################################

View File

@ -1,3 +1,11 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
###############################################################################
# Delete a key in config file
# 1 - Path of Key
@ -22,7 +30,8 @@ function writeConfigKey() {
# 2 - Path of yaml config file
# Return Value
function readConfigKey() {
local result=$(yq eval ".${1} | explode(.)" "${2}" 2>/dev/null)
local result
result=$(yq eval ".${1} | explode(.)" "${2}" 2>/dev/null)
[ "${result}" = "null" ] && echo "" || echo "${result}"
}
@ -33,13 +42,15 @@ function readConfigKey() {
function mergeConfigModules() {
# Error: bad file '-': cannot index array with '8139cp' (strconv.ParseInt: parsing "8139cp": invalid syntax)
# When the first key is a pure number, yq will not process it as a string by default. The current solution is to insert a placeholder key.
local MS="RRORG\n${1// /\\n}"
local L="$(echo -en "${MS}" | awk '{print "modules."$1":"}')"
local xmlfile=$(mktemp)
echo -en "${L}" | yq -p p -o y >"${xmlfile}"
deleteConfigKey "modules.\"RRORG\"" "${xmlfile}"
yq eval-all --inplace '. as $item ireduce ({}; . * $item)' --inplace "${2}" "${xmlfile}" 2>/dev/null
rm -f "${xmlfile}"
local MS ML XF
MS="RRORG\n${1// /\\n}"
ML="$(echo -en "${MS}" | awk '{print "modules."$1":"}')"
XF=$(mktemp 2>/dev/null)
XF=${XF:-/tmp/tmp.XXXXXXXXXX}
echo -en "${ML}" | yq -p p -o y >"${XF}"
deleteConfigKey "modules.\"RRORG\"" "${XF}"
yq eval-all --inplace '. as $item ireduce ({}; . * $item)' --inplace "${2}" "${XF}" 2>/dev/null
rm -f "${XF}"
}
###############################################################################

View File

@ -1,3 +1,13 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
# shellcheck disable=SC2034
RR_VERSION="25.2.4"
RR_RELEASE=""
RR_TITLE="RR v${RR_VERSION}"

View File

@ -1,3 +1,11 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
[ -z "${WORK_PATH}" ] || [ ! -d "${WORK_PATH}/include" ] && WORK_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/../" >/dev/null 2>&1 && pwd)"
. "${WORK_PATH}/include/consts.sh"
@ -11,7 +19,7 @@ function checkBootLoader() {
[ -z "${KNAME}" ] && continue
[ "${RO}" = "0" ] && continue
hdparm -r0 "${KNAME}" >/dev/null 2>&1 || true
done <<<$(lsblk -pno KNAME,RO 2>/dev/null)
done <<<"$(lsblk -pno KNAME,RO 2>/dev/null)"
[ ! -w "${PART1_PATH}" ] && return 1
[ ! -w "${PART2_PATH}" ] && return 1
[ ! -w "${PART3_PATH}" ] && return 1
@ -36,7 +44,7 @@ function loaderIsConfigured() {
###############################################################################
# Just show error message and dies
function die() {
echo -e "\033[1;41m$@\033[0m"
echo -e "\033[1;41m${*}\033[0m"
exit 1
}
@ -76,7 +84,6 @@ function randomhex() {
printf "%02X" $((RANDOM % 255 + 1))
}
###############################################################################
# Generate a random digit (0-9A-Z)
function genRandomDigit() {
@ -202,7 +209,7 @@ function _set_conf_kv() {
# Add if doesn't exist
echo "${1}=\"${2}\"" >>"${3}"
return $?
return 0
}
###############################################################################
@ -222,36 +229,38 @@ function _get_fastest() {
speedlist+="${I} ${speed:-999}\n" # Assign default value 999 if speed is empty
done
fi
local fastest="$(echo -e "${speedlist}" | tr -s '\n' | awk '$2 != "999"' | sort -k2n | head -1)"
local fastest
fastest="$(echo -e "${speedlist}" | tr -s '\n' | awk '$2 != "999"' | sort -k2n | head -1)"
URL="$(echo "${fastest}" | awk '{print $1}')"
SPD="$(echo "${fastest}" | awk '{print $2}')" # It is a float type
echo "${URL:-${1}}"
[ $(echo "${SPD:-999}" | cut -d. -f1) -ge 999 ] && return 1 || return 0
[ "$(echo "${SPD:-999}" | cut -d. -f1)" -ge 999 ] && return 1 || return 0
}
###############################################################################
# sort netif name
# @1 -mac1,mac2,mac3...
function _sort_netif() {
local ETHLIST=""
local ETHX="$(ls /sys/class/net/ 2>/dev/null | grep eth)" # real network cards list
for N in ${ETHX}; do
local MAC="$(cat /sys/class/net/${N}/address 2>/dev/null | sed 's/://g; s/.*/\L&/')"
local BUS="$(ethtool -i ${N} 2>/dev/null | grep bus-info | cut -d' ' -f2)"
ETHLIST="${ETHLIST}${BUS} ${MAC} ${N}\n"
ETHLIST=""
for F in /sys/class/net/eth*; do
[ ! -e "${F}" ] && continue
ETH="$(basename "${F}")"
MAC="$(cat "/sys/class/net/${ETH}/address" 2>/dev/null | sed 's/://g; s/.*/\L&/')"
BUS="$(ethtool -i "${ETH}" 2>/dev/null | grep bus-info | cut -d' ' -f2)"
ETHLIST="${ETHLIST}${BUS} ${MAC} ${ETH}\n"
done
local ETHLISTTMPM=""
local ETHLISTTMPB="$(echo -e "${ETHLIST}" | sort)"
ETHLISTTMPM=""
ETHLISTTMPB="$(echo -e "${ETHLIST}" | sort)"
if [ -n "${1}" ]; then
local MACS="$(echo "${1}" | sed 's/://g; s/,/ /g; s/.*/\L&/')"
MACS="$(echo "${1}" | sed 's/://g; s/,/ /g; s/.*/\L&/')"
for MACX in ${MACS}; do
ETHLISTTMPM="${ETHLISTTMPM}$(echo -e "${ETHLISTTMPB}" | grep "${MACX}")\n"
ETHLISTTMPB="$(echo -e "${ETHLISTTMPB}" | grep -v "${MACX}")\n"
done
fi
ETHLIST="$(echo -e "${ETHLISTTMPM}${ETHLISTTMPB}" | grep -v '^$')"
local ETHSEQ="$(echo -e "${ETHLIST}" | awk '{print $3}' | sed 's/eth//g')"
local ETHNUM="$(echo -e "${ETHLIST}" | wc -l)"
ETHSEQ="$(echo -e "${ETHLIST}" | awk '{print $3}' | sed 's/eth//g')"
ETHNUM="$(echo -e "${ETHLIST}" | wc -l)"
# echo "${ETHSEQ}"
# sort
@ -307,13 +316,14 @@ function getIP() {
# 1 - model
function getLogo() {
local MODEL="${1}"
rm -f "${PART3_PATH}/logo.png"
local fastest="$(_get_fastest "www.synology.com" "www.synology.cn")"
# [ $? -ne 0 ] && return 1
local fastest
local STATUS
local STATUS=$(curl -skL --connect-timeout 10 -w "%{http_code}" "https://${fastest}/api/products/getPhoto?product=${MODEL/+/%2B}&type=img_s&sort=0" -o "${PART3_PATH}/logo.png")
if [ $? -ne 0 ] || [ "${STATUS:-0}" -ne 200 ] || [ ! -f "${PART3_PATH}/logo.png" ]; then
rm -f "${PART3_PATH}/logo.png"
fastest="$(_get_fastest "www.synology.com" "www.synology.cn")"
STATUS=$(curl -skL --connect-timeout 10 -w "%{http_code}" "https://${fastest}/api/products/getPhoto?product=${MODEL/+/%2B}&type=img_s&sort=0" -o "${PART3_PATH}/logo.png")
if [ $? -ne 0 ] || [ "${STATUS:-0}" -ne 200 ] || [ ! -f "${PART3_PATH}/logo.png" ]; then
return 1
fi
convert -rotate 180 "${PART3_PATH}/logo.png" "${PART3_PATH}/logo.png" 2>/dev/null
@ -370,10 +380,10 @@ function delCmdline() {
function checkCPU_VT_d() {
lsmod | grep -q msr || modprobe msr 2>/dev/null
if grep -q "GenuineIntel" /proc/cpuinfo 2>/dev/null; then
local VT_D_ENABLED=$(rdmsr 0x3a 2>/dev/null)
VT_D_ENABLED=$(rdmsr 0x3a 2>/dev/null)
[ "$((${VT_D_ENABLED:-0x0} & 0x5))" -eq $((0x5)) ] && return 0
elif grep -q "AuthenticAMD" /proc/cpuinfo 2>/dev/null; then
local IOMMU_ENABLED=$(rdmsr 0xC0010114 2>/dev/null)
IOMMU_ENABLED=$(rdmsr 0xC0010114 2>/dev/null)
[ "$((${IOMMU_ENABLED:-0x0} & 0x1))" -eq $((0x1)) ] && return 0
else
return 1
@ -420,7 +430,8 @@ function connectwlanif() {
rm -f "/var/run/wpa_supplicant.pid.${1}"
fi
else
local CONF="$([ -f "${PART1_PATH}/wpa_supplicant.conf" ] && echo "${PART1_PATH}/wpa_supplicant.conf" || echo "")"
local CONF
CONF="$([ -f "${PART1_PATH}/wpa_supplicant.conf" ] && echo "${PART1_PATH}/wpa_supplicant.conf" || echo "")"
[ -z "${CONF}" ] && return 2
[ -f "/var/run/wpa_supplicant.pid.${1}" ] && return 0
wpa_supplicant -i "${1}" -c "${CONF}" -qq -B -P "/var/run/wpa_supplicant.pid.${1}" >/dev/null 2>&1

View File

@ -1,10 +1,18 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
[ -z "${WORK_PATH}" ] || [ ! -d "${WORK_PATH}/include" ] && WORK_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/../" >/dev/null 2>&1 && pwd)"
type gettext >/dev/null 2>&1 && alias TEXT='gettext "rr"' || alias TEXT='echo'
shopt -s expand_aliases
[ -d "${WORK_PATH}/lang" ] && export TEXTDOMAINDIR="${WORK_PATH}/lang"
[ -f "${PART1_PATH}/.locale" ] && export LC_ALL="$(cat "${PART1_PATH}/.locale")"
[ -f "${PART1_PATH}/.locale" ] && LC_ALL="$(cat "${PART1_PATH}/.locale")" && export LC_ALL="${LC_ALL}"
if [ -f "${PART1_PATH}/.timezone" ]; then
TIMEZONE="$(cat "${PART1_PATH}/.timezone")"

View File

@ -1,3 +1,11 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
###############################################################################
# Unpack modules from a tgz file
# 1 - Platform
@ -5,7 +13,8 @@
function unpackModules() {
local PLATFORM=${1}
local PKVER=${2}
local KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
local KERNEL
KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
rm -rf "${TMP_PATH}/modules"
mkdir -p "${TMP_PATH}/modules"
@ -23,7 +32,8 @@ function unpackModules() {
function packagModules() {
local PLATFORM=${1}
local PKVER=${2}
local KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
local KERNEL
KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
if [ "${KERNEL}" = "custom" ]; then
tar -zcf "${CKS_PATH}/modules-${PLATFORM}-${PKVER}.tgz" -C "${TMP_PATH}/modules" .
@ -46,10 +56,12 @@ function getAllModules() {
unpackModules "${PLATFORM}" "${PKVER}"
for F in $(ls ${TMP_PATH}/modules/*.ko 2>/dev/null); do
local X=$(basename "${F}")
local M=${X:0:-3}
local DESC=$(modinfo "${F}" 2>/dev/null | awk -F':' '/description:/{ print $2}' | awk '{sub(/^[ ]+/,""); print}')
for F in ${TMP_PATH}/modules/*.ko; do
[ ! -e "${F}" ] && continue
local X M DESC
X=$(basename "${F}")
M=$(basename "${F}" .ko)
DESC=$(modinfo "${F}" 2>/dev/null | awk -F':' '/description:/{ print $2}' | awk '{sub(/^[ ]+/,""); print}')
[ -z "${DESC}" ] && DESC="${X}"
echo "${M} \"${DESC}\""
done
@ -65,21 +77,23 @@ function getAllModules() {
function installModules() {
local PLATFORM=${1}
local PKVER=${2}
shift 2
local MLIST="${@}"
if [ -z "${PLATFORM}" ] || [ -z "${PKVER}" ]; then
echo "ERROR: installModules: Platform or Kernel Version not defined" >"${LOG_FILE}"
return 1
fi
local MLIST ODP KERNEL
shift 2
MLIST="${*}"
unpackModules "${PLATFORM}" "${PKVER}"
local ODP="$(readConfigKey "odp" "${USER_CONFIG_FILE}")"
for F in $(ls "${TMP_PATH}/modules/"*.ko 2>/dev/null); do
local M=$(basename "${F}")
ODP="$(readConfigKey "odp" "${USER_CONFIG_FILE}")"
for F in ${TMP_PATH}/modules/*.ko; do
[ ! -e "${F}" ] && continue
M=$(basename "${F}")
[ "${ODP}" = "true" ] && [ -f "${RAMDISK_PATH}/usr/lib/modules/${M}" ] && continue
if echo "${MLIST}" | grep -wq "${M:0:-3}"; then
if echo "${MLIST}" | grep -wq "$(basename "${M}" .ko)"; then
cp -f "${F}" "${RAMDISK_PATH}/usr/lib/modules/${M}" 2>"${LOG_FILE}"
else
rm -f "${RAMDISK_PATH}/usr/lib/modules/${M}" 2>"${LOG_FILE}"
@ -87,7 +101,7 @@ function installModules() {
done
mkdir -p "${RAMDISK_PATH}/usr/lib/firmware"
local KERNEL=$(readConfigKey "kernel" "${USER_CONFIG_FILE}")
KERNEL=$(readConfigKey "kernel" "${USER_CONFIG_FILE}")
if [ "${KERNEL}" = "custom" ]; then
tar -zxf "${CKS_PATH}/firmware.tgz" -C "${RAMDISK_PATH}/usr/lib/firmware" 2>"${LOG_FILE}"
else
@ -153,9 +167,10 @@ function delToModules() {
function getdepends() {
function _getdepends() {
if [ -f "${TMP_PATH}/modules/${1}.ko" ]; then
local depends=($(modinfo "${TMP_PATH}/modules/${1}.ko" 2>/dev/null | grep depends: | awk -F: '{print $2}' | awk '$1=$1' | sed 's/,/ /g'))
if [ ${#depends[@]} -gt 0 ]; then
for k in "${depends[@]}"; do
local depends
depends="$(modinfo "${TMP_PATH}/modules/${1}.ko" 2>/dev/null | grep depends: | awk -F: '{print $2}' | awk '$1=$1' | sed 's/,/\n/g')"
if [ "$(echo "${depends}" | wc -w)" -gt 0 ]; then
for k in ${depends}; do
echo "${k}"
_getdepends "${k}"
done
@ -174,7 +189,7 @@ function getdepends() {
unpackModules "${PLATFORM}" "${PKVER}"
local DPS=($(_getdepends "${KONAME}" | tr ' ' '\n' | sort -u))
echo "${DPS[@]}"
_getdepends "${KONAME}" | sort -u
echo "${KONAME}"
rm -rf "${TMP_PATH}/modules"
}

View File

@ -1,4 +1,10 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
set -e
[ -z "${WORK_PATH}" ] || [ ! -d "${WORK_PATH}/include" ] && WORK_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
@ -22,7 +28,7 @@ printf "\033[1;44m%*s\033[A\n" "${COLUMNS}" ""
printf "\033[1;32m%*s\033[0m\n" "${COLUMNS}" "${DATE}"
# Get first MAC address
ETHX=$(ls /sys/class/net/ 2>/dev/null | grep -v lo) || true
ETHX="$(find /sys/class/net/ -mindepth 1 -maxdepth 1 ! -name lo -exec basename {} \; | sort)"
# No network devices
[ "$(echo "${ETHX}" | wc -w)" -le 0 ] && die "$(TEXT "Network devices not found! Please re execute init.sh after connecting to the network!")"
@ -83,9 +89,9 @@ if [ ! "LOCALBUILD" = "${LOADER_DISK}" ]; then
_sort_netif "$(readConfigKey "addons.sortnetif" "${USER_CONFIG_FILE}")"
fi
for N in ${ETHX}; do
MACR="$(cat /sys/class/net/${N}/address 2>/dev/null | sed 's/://g')"
MACR="$(cat "/sys/class/net/${N}/address" 2>/dev/null | sed 's/://g')"
IPR="$(readConfigKey "network.${MACR}" "${USER_CONFIG_FILE}")"
if [ -n "${IPR}" ] && [ "1" = "$(cat /sys/class/net/${N}/carrier 2>/dev/null)" ]; then
if [ -n "${IPR}" ] && [ "1" = "$(cat "/sys/class/net/${N}/carrier" 2>/dev/null)" ]; then
IFS='/' read -r -a IPRA <<<"${IPR}"
ip addr flush dev "${N}"
ip addr add "${IPRA[0]}/${IPRA[1]:-"255.255.255.0"}" dev "${N}"
@ -167,7 +173,7 @@ COUNT=0
while [ ${COUNT} -lt 30 ]; do
MSG=""
for N in ${ETHX}; do
if [ "1" = "$(cat /sys/class/net/${N}/carrier 2>/dev/null)" ]; then
if [ "1" = "$(cat "/sys/class/net/${N}/carrier" 2>/dev/null)" ]; then
MSG+="${N} "
fi
done
@ -185,15 +191,15 @@ done
printf "$(TEXT "Waiting IP.\n")"
for N in ${ETHX}; do
COUNT=0
DRIVER=$(ls -ld /sys/class/net/${N}/device/driver 2>/dev/null | awk -F '/' '{print $NF}')
MAC=$(cat /sys/class/net/${N}/address 2>/dev/null)
DRIVER="$(basename "$(realpath "/sys/class/net/${N}/device/driver" 2>/dev/null)" 2>/dev/null)"
MAC="$(cat "/sys/class/net/${N}/address" 2>/dev/null)"
printf "%s(%s): " "${N}" "${MAC}@${DRIVER}"
while true; do
if [ -z "$(cat /sys/class/net/${N}/carrier 2>/dev/null)" ]; then
if [ -z "$(cat "/sys/class/net/${N}/carrier" 2>/dev/null)" ]; then
printf "\r%s(%s): %s\n" "${N}" "${MAC}@${DRIVER}" "$(TEXT "DOWN")"
break
fi
if [ "0" = "$(cat /sys/class/net/${N}/carrier 2>/dev/null)" ]; then
if [ "0" = "$(cat "/sys/class/net/${N}/carrier" 2>/dev/null)" ]; then
printf "\r%s(%s): %s\n" "${N}" "${MAC}@${DRIVER}" "$(TEXT "NOT CONNECTED")"
break
fi
@ -246,7 +252,7 @@ if [ "${DSMLOGO}" = "true" ] && [ -c "/dev/fb0" ] && [ ! "LOCALBUILD" = "${LOADE
fi
# Check memory
RAM=$(awk '/MemTotal:/ {printf "%.0f", $2 / 1024}' /proc/meminfo 2>/dev/null)
RAM="$(awk '/MemTotal:/ {printf "%.0f", $2 / 1024}' /proc/meminfo 2>/dev/null)"
if [ "${RAM:-0}" -le 3500 ]; then
printf "\033[1;33m%s\033[0m\n" "$(TEXT "You have less than 4GB of RAM, if errors occur in loader creation, please increase the amount of memory.")"
fi

View File

@ -1,4 +1,12 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
# shellcheck disable=SC2010,SC2034,SC2115,SC2120
[ -z "${WORK_PATH}" ] || [ ! -d "${WORK_PATH}/include" ] && WORK_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
@ -148,7 +156,7 @@ function modelMenu() {
NVMEMD=$(find /sys/devices -type d -name nvme | awk -F'/' '{print NF}' | sort -n | tail -n1)
if [ -n "${IGPUID}" ]; then grep -iq "${IGPUID}" ${WORK_PATH}/i915ids && hasiGPU=1 || hasiGPU=2; else hasiGPU=0; fi
if [ ${NVMEMD:-0} -lt 6 ]; then hasNVME=0; elif [ ${NVMEMD:-0} -eq 6 ]; then hasNVME=1; else hasNVME=2; fi
[ "$(lspci -d ::104 2>/dev/null | wc -l)" -gt 0 -o "$(lspci -d ::107 2>/dev/null | wc -l)" -gt 0 ] && hasHBA=1 || hasHBA=0
[ "$(lspci -d ::104 2>/dev/null | wc -l)" -gt 0 ] || [ "$(lspci -d ::107 2>/dev/null | wc -l)" -gt 0 ] && hasHBA=1 || hasHBA=0
while read -r M A; do
COMPATIBLE=1
if [ ${RESTRICT} -eq 1 ]; then
@ -345,8 +353,9 @@ function productversMenu() {
DIALOG --title "$(TEXT "Product Version")" \
--infobox "$(TEXT "Reconfiguring Synoinfo, Addons and Modules ...")" 0 0
fi
local BASEPATURL="$(readConfigKey "paturl" "${USER_CONFIG_FILE}")"
local BASEPATSUM="$(readConfigKey "patsum" "${USER_CONFIG_FILE}")"
local BASEPATURL BASEPATSUM
BASEPATURL="$(readConfigKey "paturl" "${USER_CONFIG_FILE}")"
BASEPATSUM="$(readConfigKey "patsum" "${USER_CONFIG_FILE}")"
PRODUCTVER=${selver}
writeConfigKey "productver" "${PRODUCTVER}" "${USER_CONFIG_FILE}"
@ -382,7 +391,7 @@ function productversMenu() {
writeConfigKey "synoinfo" "{}" "${USER_CONFIG_FILE}"
while IFS=': ' read -r KEY VALUE; do
writeConfigKey "synoinfo.\"${KEY}\"" "${VALUE}" "${USER_CONFIG_FILE}"
done <<<$(readConfigMap "platforms.${PLATFORM}.synoinfo" "${WORK_PATH}/platforms.yml")
done <<<"$(readConfigMap "platforms.${PLATFORM}.synoinfo" "${WORK_PATH}/platforms.yml")"
# Check addons
while IFS=': ' read -r ADDON PARAM; do
@ -390,7 +399,7 @@ function productversMenu() {
if ! checkAddonExist "${ADDON}" "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}"; then
deleteConfigKey "addons.\"${ADDON}\"" "${USER_CONFIG_FILE}"
fi
done <<<$(readConfigMap "addons" "${USER_CONFIG_FILE}")
done <<<"$(readConfigMap "addons" "${USER_CONFIG_FILE}")"
# Rewrite modules
writeConfigKey "modules" "{}" "${USER_CONFIG_FILE}"
mergeConfigModules "$(getAllModules "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}" | awk '{print $1}')" "${USER_CONFIG_FILE}"
@ -481,7 +490,7 @@ function setConfigFromDSM() {
writeConfigKey "synoinfo" "{}" "${USER_CONFIG_FILE}"
while IFS=': ' read -r KEY VALUE; do
writeConfigKey "synoinfo.\"${KEY}\"" "${VALUE}" "${USER_CONFIG_FILE}"
done <<<$(readConfigMap "platforms.${PLATFORM}.synoinfo" "${WORK_PATH}/platforms.yml")
done <<<"$(readConfigMap "platforms.${PLATFORM}.synoinfo" "${WORK_PATH}/platforms.yml")"
# Check addons
while IFS=': ' read -r ADDON PARAM; do
@ -489,7 +498,7 @@ function setConfigFromDSM() {
if ! checkAddonExist "${ADDON}" "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}"; then
deleteConfigKey "addons.\"${ADDON}\"" "${USER_CONFIG_FILE}"
fi
done <<<$(readConfigMap "addons" "${USER_CONFIG_FILE}")
done <<<"$(readConfigMap "addons" "${USER_CONFIG_FILE}")"
# Rebuild modules
writeConfigKey "modules" "{}" "${USER_CONFIG_FILE}"
@ -602,7 +611,7 @@ function addonMenu() {
declare -A ADDONS
while IFS=': ' read -r KEY VALUE; do
[ -n "${KEY}" ] && ADDONS["${KEY}"]="${VALUE}"
done <<<$(readConfigMap "addons" "${USER_CONFIG_FILE}")
done <<<"$(readConfigMap "addons" "${USER_CONFIG_FILE}")"
rm -f "${TMP_PATH}/menu"
{
echo "a \"$(TEXT "Add an addon")\""
@ -622,7 +631,7 @@ function addonMenu() {
while read -r ADDON DESC; do
arrayExistItem "${ADDON}" "${!ADDONS[@]}" && continue # Check if addon has already been added
echo "${ADDON} \"${DESC}\"" >>"${TMP_PATH}/menu"
done <<<$(availableAddons "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}")
done <<<"$(availableAddons "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}")"
if [ ! -f "${TMP_PATH}/menu" ]; then
DIALOG --title "$(TEXT "Addons")" \
--msgbox "$(TEXT "No available addons to add")" 0 0
@ -665,7 +674,7 @@ function addonMenu() {
ADDON="$(cat "${TMP_PATH}/resp")"
[ -z "${ADDON}" ] && continue
for I in ${ADDON}; do
unset ADDONS[${I}]
unset "ADDONS[${I}]"
deleteConfigKey "addons.\"${I}\"" "${USER_CONFIG_FILE}"
done
touch ${PART1_PATH}/.build
@ -680,7 +689,7 @@ function addonMenu() {
MSG+="${MODULE}"
fi
MSG+=": \Z5${DESC}\Zn\n"
done <<<$(availableAddons "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}")
done <<<"$(availableAddons "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}")"
DIALOG --title "$(TEXT "Addons")" \
--msgbox "${MSG}" 0 0
;;
@ -693,28 +702,26 @@ function addonMenu() {
fi
DIALOG --title "$(TEXT "Addons")" \
--msgbox "$(TEXT "Please upload the *.addon file.")" 0 0
TMP_UP_PATH=${TMP_PATH}/users
USER_FILE=""
rm -rf ${TMP_UP_PATH}
mkdir -p ${TMP_UP_PATH}
pushd ${TMP_UP_PATH}
rz -be
for F in $(ls -A 2>/dev/null); do
USER_FILE=${F}
break
done
popd
TMP_UP_PATH="${TMP_PATH}/users"
rm -rf "${TMP_UP_PATH}"
mkdir -p "${TMP_UP_PATH}"
(cd "${TMP_UP_PATH}" && rz -be) || true
USER_FILE="$(find "${TMP_UP_PATH}" -type f | head -1)"
if [ -z "${USER_FILE}" ]; then
DIALOG --title "$(TEXT "Addons")" \
--msgbox "$(TEXT "Not a valid file, please try again!")" 0 0
else
if [ -d "${ADDONS_PATH}/$(basename ${USER_FILE} .addon)" ]; then
if [ -d "${ADDONS_PATH}/$(basename "${USER_FILE}" .addon)" ]; then
DIALOG --title "$(TEXT "Addons")" \
--yesno "$(TEXT "The addon already exists. Do you want to overwrite it?")" 0 0
RET=$?
[ ${RET} -ne 0 ] && return
if [ ${RET} -ne 0 ]; then
rm -rf "${TMP_UP_PATH}"
return
fi
ADDON="$(untarAddon "${TMP_UP_PATH}/${USER_FILE}")"
fi
ADDON="$(untarAddon "${USER_FILE}")"
rm -rf "${TMP_UP_PATH}"
if [ -n "${ADDON}" ]; then
[ -f "${ADDONS_PATH}/VERSION" ] && rm -f "${ADDONS_PATH}/VERSION"
DIALOG --title "$(TEXT "Addons")" \
@ -763,7 +770,7 @@ function moduleMenu() {
declare -A USERMODULES
while IFS=': ' read -r KEY VALUE; do
[ -n "${KEY}" ] && USERMODULES["${KEY}"]="${VALUE}"
done <<<$(readConfigMap "modules" "${USER_CONFIG_FILE}")
done <<<"$(readConfigMap "modules" "${USER_CONFIG_FILE}")"
rm -f "${TMP_PATH}/opts"
while read -r ID DESC; do
arrayExistItem "${ID}" "${!USERMODULES[@]}" && ACT="on" || ACT="off"
@ -808,14 +815,11 @@ function moduleMenu() {
l)
DIALOG --title "$(TEXT "Modules")" \
--infobox "$(TEXT "Selecting loaded modules")" 0 0
KOLIST=""
for I in $(lsmod 2>/dev/null | awk -F' ' '{print $1}' | grep -v 'Module'); do
KOLIST+="$(getdepends "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}" "${I}") ${I} "
done
KOLIST=($(echo ${KOLIST} | tr ' ' '\n' | sort -u))
writeConfigKey "modules" "{}" "${USER_CONFIG_FILE}"
for ID in ${KOLIST[@]}; do
writeConfigKey "modules.\"${ID}\"" "" "${USER_CONFIG_FILE}"
for I in $(lsmod 2>/dev/null | awk -F' ' '{print $1}' | grep -v 'Module'); do
while read -r J; do
writeConfigKey "modules.\"${J}\"" "" "${USER_CONFIG_FILE}"
done <<<"$(getdepends "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}" "${I}")"
done
touch ${PART1_PATH}/.build
;;
@ -838,47 +842,42 @@ function moduleMenu() {
[ $? -ne 0 ] && continue
DIALOG --title "$(TEXT "Modules")" \
--msgbox "$(TEXT "Please upload the *.ko file.")" 0 0
TMP_UP_PATH=${TMP_PATH}/users
USER_FILE=""
rm -rf ${TMP_UP_PATH}
mkdir -p ${TMP_UP_PATH}
pushd ${TMP_UP_PATH}
rz -be
for F in $(ls -A 2>/dev/null); do
USER_FILE=${F}
break
done
popd
TMP_UP_PATH="${TMP_PATH}/users"
rm -rf "${TMP_UP_PATH}"
mkdir -p "${TMP_UP_PATH}"
(cd "${TMP_UP_PATH}" && rz -be) || true
USER_FILE="$(find "${TMP_UP_PATH}" -type f | head -1)"
if [ -n "${USER_FILE}" ] && [ "${USER_FILE##*.}" = "ko" ]; then
addToModules ${PLATFORM} "${KPRE:+${KPRE}-}${KVER}" "${TMP_UP_PATH}/${USER_FILE}"
addToModules "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}" "${USER_FILE}"
[ -f "${MODULES_PATH}/VERSION" ] && rm -f "${MODULES_PATH}/VERSION"
DIALOG --title "$(TEXT "Modules")" \
--msgbox "$(printf "$(TEXT "Module '%s' added to %s-%s")" "${USER_FILE}" "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}")" 0 0
rm -f "${TMP_UP_PATH}/${USER_FILE}"
--msgbox "$(printf "$(TEXT "Module '%s' added to %s-%s")" "$(basename "${USER_FILE}" .ko)" "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}")" 0 0
rm -rf "${TMP_UP_PATH}"
touch ${PART1_PATH}/.build
else
DIALOG --title "$(TEXT "Modules")" \
--msgbox "$(TEXT "Not a valid file, please try again!")" 0 0
rm -rf "${TMP_UP_PATH}"
fi
;;
i)
DEPS="$(getdepends "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}" i915) i915"
DEPS="$(getdepends "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}" i915)"
DELS=()
while IFS=': ' read -r KEY VALUE; do
[ -z "${KEY}" ] && continue
if echo "${DEPS}" | grep -wq "${KEY}"; then
DELS+=("${KEY}")
fi
done <<<$(readConfigMap "modules" "${USER_CONFIG_FILE}")
done <<<"$(readConfigMap "modules" "${USER_CONFIG_FILE}")"
if [ ${#DELS[@]} -eq 0 ]; then
DIALOG --title "$(TEXT "Modules")" \
--msgbox "$(TEXT "No i915 with dependencies module to deselect.")" 0 0
else
for ID in ${DELS[@]}; do
for ID in "${DELS[@]}"; do
deleteConfigKey "modules.\"${ID}\"" "${USER_CONFIG_FILE}"
done
DIALOG --title "$(TEXT "Modules")" \
--msgbox "$(printf "$(TEXT "Module %s deselected.")" "${DELS[@]}")" 0 0
--msgbox "$(printf "$(TEXT "Module %s deselected.")\n" "${DELS[@]}")" 0 0
fi
touch ${PART1_PATH}/.build
;;
@ -1020,7 +1019,7 @@ function cmdlineMenu() {
declare -A CMDLINE
while IFS=': ' read -r KEY VALUE; do
[ -n "${KEY}" ] && CMDLINE["${KEY}"]="${VALUE}"
done <<<$(readConfigMap "cmdline" "${USER_CONFIG_FILE}")
done <<<"$(readConfigMap "cmdline" "${USER_CONFIG_FILE}")"
if [ ${#CMDLINE[@]} -eq 0 ]; then
DIALOG --title "$(TEXT "Cmdline")" \
--msgbox "$(TEXT "No user cmdline to remove")" 0 0
@ -1037,7 +1036,7 @@ function cmdlineMenu() {
RESP=$(cat "${TMP_PATH}/resp")
[ -z "${RESP}" ] && continue
for I in ${RESP}; do
unset CMDLINE[${I}]
unset "CMDLINE[${I}]"
deleteConfigKey "cmdline.\"${I}\"" "${USER_CONFIG_FILE}"
done
;;
@ -1181,14 +1180,14 @@ function synoinfoMenu() {
declare -A SYNOINFO
while IFS=': ' read -r KEY VALUE; do
[ -n "${KEY}" ] && SYNOINFO["${KEY}"]="${VALUE}"
done <<<$(readConfigMap "synoinfo" "${USER_CONFIG_FILE}")
done <<<"$(readConfigMap "synoinfo" "${USER_CONFIG_FILE}")"
if [ ${#SYNOINFO[@]} -eq 0 ]; then
DIALOG --title "$(TEXT "Synoinfo")" \
--msgbox "$(TEXT "No synoinfo entries to remove")" 0 0
continue
fi
rm -f "${TMP_PATH}/opts"
for I in ${!SYNOINFO[@]}; do
for I in "${!SYNOINFO[@]}"; do
echo "\"${I}\" \"${SYNOINFO[${I}]}\" \"off\"" >>"${TMP_PATH}/opts"
done
DIALOG --title "$(TEXT "Synoinfo")" \
@ -1198,7 +1197,7 @@ function synoinfoMenu() {
RESP=$(cat "${TMP_PATH}/resp")
[ -z "${RESP}" ] && continue
for I in ${RESP}; do
unset SYNOINFO[${I}]
unset "SYNOINFO[${I}]"
deleteConfigKey "synoinfo.\"${I}\"" "${USER_CONFIG_FILE}"
done
touch ${PART1_PATH}/.build
@ -1215,7 +1214,7 @@ function synoinfoMenu() {
function getSynoExtractor() {
rm -f "${LOG_FILE}"
mirrors=("global.synologydownload.com" "global.download.synology.com" "cndl.synology.cn")
fastest=$(_get_fastest ${mirrors[@]})
fastest=$(_get_fastest "${mirrors[@]}")
if [ $? -ne 0 ]; then
echo -e "$(TEXT "The current network status is unknown, using the default mirror.")"
fi
@ -1358,7 +1357,7 @@ function extractDsmFiles() {
fi
mkdir -p "${PART3_PATH}/dl"
mirrors=("global.synologydownload.com" "global.download.synology.com" "cndl.synology.cn")
fastest=$(_get_fastest ${mirrors[@]})
fastest=$(_get_fastest "${mirrors[@]}")
if [ $? -ne 0 ]; then
echo -e "$(TEXT "The current network status is unknown, using the default mirror.")"
fi
@ -1536,20 +1535,14 @@ function customDTS() {
DIALOG --title "$(TEXT "Custom DTS")" \
--msgbox "$(TEXT "Currently, only dts format files are supported. Please prepare and click to confirm uploading.\n(saved in /mnt/p3/users/)\n")" 0 0
TMP_UP_PATH="${TMP_PATH}/users"
DTC_ERRLOG="/tmp/dtc.log"
rm -rf "${TMP_UP_PATH}"
mkdir -p "${TMP_UP_PATH}"
pushd "${TMP_UP_PATH}"
RET=1
rz -be
for F in $(ls -A 2>/dev/null); do
USER_FILE="${TMP_UP_PATH}/${F}"
dtc -q -I dts -O dtb "${F}" >"test.dtb" 2>"${DTC_ERRLOG}"
(cd "${TMP_UP_PATH}" && rz -be) || true
USER_FILE="$(find "${TMP_UP_PATH}" -type f | head -1)"
DTC_ERRLOG="/tmp/dtc.log"
[ -z "${USER_FILE}" ] && dtc -q -I dts -O dtb "${USER_FILE}" >"test.dtb" 2>"${DTC_ERRLOG}"
RET=$?
break
done
popd
if [ ${RET} -ne 0 ] || [ -z "${USER_FILE}" ]; then
if [ -z "${USER_FILE}" ] || [ ${RET} -ne 0 ]; then
MSG="$(printf "%s\n%s:\n%s\n" "$(TEXT "Not a valid dts file, please try again!")" "$(TEXT "Error")" "$(cat "${DTC_ERRLOG}")")"
DIALOG --title "$(TEXT "Custom DTS")" \
--msgbox "${MSG}" 0 0
@ -1559,7 +1552,8 @@ function customDTS() {
DIALOG --title "$(TEXT "Custom DTS")" \
--msgbox "$(TEXT "A valid dts file, Automatically import at compile time.")" 0 0
fi
rm -rf "${DTC_ERRLOG}"
rm -f "${DTC_ERRLOG}"
rm -rf "${TMP_UP_PATH}"
touch ${PART1_PATH}/.build
;;
d)
@ -1571,7 +1565,7 @@ function customDTS() {
if [ -f "${USER_UP_PATH}/${MODEL}.dts" ]; then
cp -f "${USER_UP_PATH}/${MODEL}.dts" "${TMP_PATH}/model.dts"
else
ODTB="$(ls ${PART2_PATH}/*.dtb 2>/dev/null | head -1)"
ODTB="$(find "${PART2_PATH}" -type f -name "*.dtb" | head -1)"
if [ -f "${ODTB}" ]; then
dtc -q -I dtb -O dts "${ODTB}" >"${TMP_PATH}/model.dts"
else
@ -1611,7 +1605,7 @@ function customDTS() {
function showDisksInfo() {
MSG=""
NUMPORTS=0
[ $(lspci -d ::106 2>/dev/null | wc -l) -gt 0 ] && MSG+="\nSATA:\n"
[ "$(lspci -d ::106 2>/dev/null | wc -l)" -gt 0 ] && MSG+="\nSATA:\n"
for PCI in $(lspci -d ::106 2>/dev/null | awk '{print $1}'); do
NAME=$(lspci -s "${PCI}" 2>/dev/null | sed "s/\ .*://")
MSG+="\Zb${NAME}\Zn\nPorts: "
@ -1630,7 +1624,7 @@ function showDisksInfo() {
done
MSG+="\n"
done
[ $(lspci -d ::104 2>/dev/null | wc -l) -gt 0 ] && MSG+="\nRAID:\n"
[ "$(lspci -d ::104 2>/dev/null | wc -l)" -gt 0 ] && MSG+="\nRAID:\n"
for PCI in $(lspci -d ::104 2>/dev/null | awk '{print $1}'); do
NAME=$(lspci -s "${PCI}" 2>/dev/null | sed "s/\ .*://")
PORT=$(ls -l /sys/class/scsi_host 2>/dev/null | grep "${PCI}" | awk -F'/' '{print $NF}' | sed 's/host//' | sort -n)
@ -1639,7 +1633,7 @@ function showDisksInfo() {
MSG+="\Zb${NAME}\Zn\nNumber: ${PORTNUM}\n"
NUMPORTS=$((${NUMPORTS} + ${PORTNUM}))
done
[ $(lspci -d ::107 2>/dev/null | wc -l) -gt 0 ] && MSG+="\nSAS:\n"
[ "$(lspci -d ::107 2>/dev/null | wc -l)" -gt 0 ] && MSG+="\nSAS:\n"
for PCI in $(lspci -d ::107 2>/dev/null | awk '{print $1}'); do
NAME=$(lspci -s "${PCI}" 2>/dev/null | sed "s/\ .*://")
PORT=$(ls -l /sys/class/scsi_host 2>/dev/null | grep "${PCI}" | awk -F'/' '{print $NF}' | sed 's/host//' | sort -n)
@ -1648,7 +1642,7 @@ function showDisksInfo() {
MSG+="\Zb${NAME}\Zn\nNumber: ${PORTNUM}\n"
NUMPORTS=$((${NUMPORTS} + ${PORTNUM}))
done
[ $(lspci -d ::100 2>/dev/null | wc -l) -gt 0 ] && MSG+="\nSCSI:\n"
[ "$(lspci -d ::100 2>/dev/null | wc -l)" -gt 0 ] && MSG+="\nSCSI:\n"
for PCI in $(lspci -d ::100 2>/dev/null | awk '{print $1}'); do
NAME=$(lspci -s "${PCI}" 2>/dev/null | sed "s/\ .*://")
PORTNUM=$(ls -l /sys/block/* 2>/dev/null | grep "${PCI}" | wc -l)
@ -1656,7 +1650,7 @@ function showDisksInfo() {
MSG+="\Zb${NAME}\Zn\nNumber: ${PORTNUM}\n"
NUMPORTS=$((${NUMPORTS} + ${PORTNUM}))
done
[ $(lspci -d ::101 2>/dev/null | wc -l) -gt 0 ] && MSG+="\nIDE:\n"
[ "$(lspci -d ::101 2>/dev/null | wc -l)" -gt 0 ] && MSG+="\nIDE:\n"
for PCI in $(lspci -d ::101 2>/dev/null | awk '{print $1}'); do
NAME=$(lspci -s "${PCI}" 2>/dev/null | sed "s/\ .*://")
PORTNUM=$(ls -l /sys/block/* 2>/dev/null | grep "${PCI}" | wc -l)
@ -1664,7 +1658,7 @@ function showDisksInfo() {
MSG+="\Zb${NAME}\Zn\nNumber: ${PORTNUM}\n"
NUMPORTS=$((${NUMPORTS} + ${PORTNUM}))
done
[ $(ls -l /sys/class/scsi_host 2>/dev/null | grep usb | wc -l) -gt 0 ] && MSG+="\nUSB:\n"
[ "$(ls -l /sys/class/scsi_host 2>/dev/null | grep usb | wc -l)" -gt 0 ] && MSG+="\nUSB:\n"
for PCI in $(lspci -d ::c03 2>/dev/null | awk '{print $1}'); do
NAME=$(lspci -s "${PCI}" 2>/dev/null | sed "s/\ .*://")
PORT=$(ls -l /sys/class/scsi_host 2>/dev/null | grep "${PCI}" | awk -F'/' '{print $NF}' | sed 's/host//' | sort -n)
@ -1673,7 +1667,7 @@ function showDisksInfo() {
MSG+="\Zb${NAME}\Zn\nNumber: ${PORTNUM}\n"
NUMPORTS=$((${NUMPORTS} + ${PORTNUM}))
done
[ $(ls -l /sys/block/mmc* | wc -l) -gt 0 ] && MSG+="\nMMC:\n"
[ "$(ls -l /sys/block/mmc* 2>/dev/null | wc -l)" -gt 0 ] && MSG+="\nMMC:\n"
for PCI in $(lspci -d ::805 2>/dev/null | awk '{print $1}'); do
NAME=$(lspci -s "${PCI}" 2>/dev/null | sed "s/\ .*://")
PORTNUM=$(ls -l /sys/block/mmc* 2>/dev/null | grep "${PCI}" | wc -l)
@ -1681,7 +1675,7 @@ function showDisksInfo() {
MSG+="\Zb${NAME}\Zn\nNumber: ${PORTNUM}\n"
NUMPORTS=$((${NUMPORTS} + ${PORTNUM}))
done
[ $(lspci -d ::108 2>/dev/null | wc -l) -gt 0 ] && MSG+="\nNVME:\n"
[ "$(lspci -d ::108 2>/dev/null | wc -l)" -gt 0 ] && MSG+="\nNVME:\n"
for PCI in $(lspci -d ::108 2>/dev/null | awk '{print $1}'); do
NAME=$(lspci -s "${PCI}" 2>/dev/null | sed "s/\ .*://")
PORT=$(ls -l /sys/class/nvme 2>/dev/null | grep "${PCI}" | awk -F'/' '{print $NF}' | sed 's/nvme//' | sort -n)
@ -1690,7 +1684,7 @@ function showDisksInfo() {
MSG+="\Zb${NAME}\Zn\nNumber: ${PORTNUM}\n"
NUMPORTS=$((${NUMPORTS} + ${PORTNUM}))
done
if [ $(lsblk -dpno KNAME,SUBSYSTEMS 2>/dev/null | grep 'vmbus:acpi' | wc -l) -gt 0 ]; then
if [ "$(lsblk -dpno KNAME,SUBSYSTEMS 2>/dev/null | grep 'vmbus:acpi' | wc -l)" -gt 0 ]; then
MSG+="\nVMBUS:\n"
NAME="vmbus:acpi"
PORTNUM=$(lsblk -dpno KNAME,SUBSYSTEMS 2>/dev/null | grep 'vmbus:acpi' | wc -l)
@ -1744,7 +1738,7 @@ function formatDisks() {
[ "${KNAME:0:7}" = "/dev/md" ] && continue
[ "${KNAME}" = "${LOADER_DISK}" ] || [ "${PKNAME}" = "${LOADER_DISK}" ] && continue
printf "\"%s\" \"%-6s %-4s %s\" \"off\"\n" "${KNAME}" "${SIZE}" "${TYPE}" "${ID}" >>"${TMP_PATH}/opts"
done <<<$(lsblk -Jpno KNAME,ID,SIZE,TYPE,PKNAME 2>/dev/null | sed 's|null|"N/A"|g' | jq -r '.blockdevices[] | "\(.kname) \(.id) \(.size) \(.type) \(.pkname)"' 2>/dev/null)
done <<<"$(lsblk -Jpno KNAME,ID,SIZE,TYPE,PKNAME 2>/dev/null | sed 's|null|"N/A"|g' | jq -r '.blockdevices[] | "\(.kname) \(.id) \(.size) \(.type) \(.pkname)"' 2>/dev/null)"
if [ ! -f "${TMP_PATH}/opts" ]; then
DIALOG --title "$(TEXT "Advanced")" \
--msgbox "$(TEXT "No disk found!")" 0 0
@ -1759,12 +1753,13 @@ function formatDisks() {
DIALOG --title "$(TEXT "Advanced")" \
--yesno "$(TEXT "Warning:\nThis operation is irreversible. Please backup important data. Do you want to continue?")" 0 0
[ $? -ne 0 ] && return
if [ $(ls /dev/md[0-9]* 2>/dev/null | wc -l) -gt 0 ]; then
if [ "$(ls /dev/md[0-9]* 2>/dev/null | wc -l)" -gt 0 ]; then
DIALOG --title "$(TEXT "Advanced")" \
--yesno "$(TEXT "Warning:\nThe current hds is in raid, do you still want to format them?")" 0 0
[ $? -ne 0 ] && return
for I in $(ls /dev/md[0-9]* 2>/dev/null); do
mdadm -S "${I}" >/dev/null 2>&1
for F in /dev/md[0-9]*; do
[ ! -e "${F}" ] && continue
mdadm -S "${F}" >/dev/null 2>&1
done
fi
for I in ${RESP}; do
@ -1871,7 +1866,7 @@ function resetDSMPassword() {
grep -q "status=on" "${TMP_PATH}/mdX/usr/syno/etc/packages/SecureSignIn/preference/${U}/method.config" 2>/dev/null
[ $? -eq 0 ] && S="SecureSignIn" || S=" "
printf "\"%-36s %-10s %-14s\"\n" "${U}" "${E}" "${S}" >>"${TMP_PATH}/menu"
done <<<$(cat "${TMP_PATH}/mdX/etc/shadow" 2>/dev/null)
done <<<"$(cat "${TMP_PATH}/mdX/etc/shadow" 2>/dev/null)"
fi
umount "${TMP_PATH}/mdX"
[ -f "${TMP_PATH}/menu" ] && break
@ -1901,9 +1896,10 @@ function resetDSMPassword() {
rm -f "${TMP_PATH}/isOk"
(
mkdir -p "${TMP_PATH}/mdX"
# local NEWPASSWD="$(python3 -c "from passlib.hash import sha512_crypt;pw=\"${VALUE}\";print(sha512_crypt.using(rounds=5000).hash(pw))")"
# local NEWPASSWD="$(echo "${VALUE}" | mkpasswd -m sha512)"
local NEWPASSWD="$(openssl passwd -6 -salt $(openssl rand -hex 8) "${VALUE}")"
local NEWPASSWD
# NEWPASSWD="$(python3 -c "from passlib.hash import sha512_crypt;pw=\"${VALUE}\";print(sha512_crypt.using(rounds=5000).hash(pw))")"
# NEWPASSWD="$(echo "${VALUE}" | mkpasswd -m sha512)"
NEWPASSWD="$(openssl passwd -6 -salt "$(openssl rand -hex 8)" "${VALUE}")"
for I in ${DSMROOTS}; do
fixDSMRootPart "${I}"
mount -t ext4 "${I}" "${TMP_PATH}/mdX"
@ -1957,7 +1953,7 @@ function addNewDSMUser() {
if [ -f "${TMP_PATH}/mdX/usr/syno/etc/esynoscheduler/esynoscheduler.db" ]; then
sqlite3 ${TMP_PATH}/mdX/usr/syno/etc/esynoscheduler/esynoscheduler.db <<EOF
DELETE FROM task WHERE task_name LIKE 'RRONBOOTUPRR_ADDUSER';
INSERT INTO task VALUES('RRONBOOTUPRR_ADDUSER', '', 'bootup', '', 1, 0, 0, 0, '', 0, '$(echo -e ${ONBOOTUP})', 'script', '{}', '', '', '{}', '{}');
INSERT INTO task VALUES('RRONBOOTUPRR_ADDUSER', '', 'bootup', '', 1, 0, 0, 0, '', 0, '$(echo -e "${ONBOOTUP}")', 'script', '{}', '', '', '{}', '{}');
EOF
sync
echo "true" >"${TMP_PATH}/isOk"
@ -1998,7 +1994,7 @@ function forceEnableDSMTelnetSSH() {
if [ -f "${TMP_PATH}/mdX/usr/syno/etc/esynoscheduler/esynoscheduler.db" ]; then
sqlite3 ${TMP_PATH}/mdX/usr/syno/etc/esynoscheduler/esynoscheduler.db <<EOF
DELETE FROM task WHERE task_name LIKE 'RRONBOOTUPRR_SSH';
INSERT INTO task VALUES('RRONBOOTUPRR_SSH', '', 'bootup', '', 1, 0, 0, 0, '', 0, '$(echo -e ${ONBOOTUP})', 'script', '{}', '', '', '{}', '{}');
INSERT INTO task VALUES('RRONBOOTUPRR_SSH', '', 'bootup', '', 1, 0, 0, 0, '', 0, '$(echo -e "${ONBOOTUP}")', 'script', '{}', '', '', '{}', '{}');
EOF
sync
echo "true" >"${TMP_PATH}/isOk"
@ -2134,7 +2130,7 @@ function languageMenu() {
while read -r L; do
A="$(echo "$(strings "${WORK_PATH}/lang/${L}/LC_MESSAGES/rr.mo" 2>/dev/null | grep "Last-Translator" | sed "s/Last-Translator://")")"
echo "${L} \"${A:-"anonymous"}\"" >>"${TMP_PATH}/menu"
done <<<$(ls ${WORK_PATH}/lang/*/LC_MESSAGES/rr.mo 2>/dev/null | sort | sed -E 's/.*\/lang\/(.*)\/LC_MESSAGES\/rr\.mo$/\1/')
done <<<"$(ls ${WORK_PATH}/lang/*/LC_MESSAGES/rr.mo 2>/dev/null | sort | sed -E 's/.*\/lang\/(.*)\/LC_MESSAGES\/rr\.mo$/\1/')"
DIALOG --title "$(TEXT "Settings")" \
--default-item "${LAYOUT}" --menu "$(TEXT "Choose a language")" 0 0 20 --file "${TMP_PATH}/menu" \
@ -2322,7 +2318,7 @@ function cloneBootloaderDisk() {
[ "${KNAME}" = "N/A" ] || [ "${SIZE:0:1}" = "0" ] && continue
[ "${KNAME}" = "${LOADER_DISK}" ] || [ "${PKNAME}" = "${LOADER_DISK}" ] && continue
printf "\"%s\" \"%-6s %s\" \"off\"\n" "${KNAME}" "${SIZE}" "${ID}" >>"${TMP_PATH}/opts"
done <<<$(lsblk -Jdpno KNAME,ID,SIZE,PKNAME 2>/dev/null | sed 's|null|"N/A"|g' | jq -r '.blockdevices[] | "\(.kname) \(.id) \(.size) \(.pkname)"' 2>/dev/null)
done <<<"$(lsblk -Jdpno KNAME,ID,SIZE,PKNAME 2>/dev/null | sed 's|null|"N/A"|g' | jq -r '.blockdevices[] | "\(.kname) \(.id) \(.size) \(.pkname)"' 2>/dev/null)"
if [ ! -f "${TMP_PATH}/opts" ]; then
DIALOG --title "$(TEXT "Settings")" \
@ -2613,9 +2609,9 @@ function savemodrr() {
###############################################################################
# Set static IP
function setStaticIP() {
ETHX=$(ls /sys/class/net/ 2>/dev/null | grep -v lo) || true
ETHX="$(find /sys/class/net/ -mindepth 1 -maxdepth 1 ! -name lo -exec basename {} \; | sort)"
for N in ${ETHX}; do
MACR="$(cat /sys/class/net/${N}/address 2>/dev/null | sed 's/://g')"
MACR="$(cat "/sys/class/net/${N}/address" 2>/dev/null | sed 's/://g')"
IPR="$(readConfigKey "network.${MACR}" "${USER_CONFIG_FILE}")"
IFS='/' read -r -a IPRA <<<"${IPR}"
@ -2739,7 +2735,8 @@ function setWirelessAccount() {
# $1 - KEY
function setProxy() {
local RET=1
local PROXY=$(readConfigKey "${1}" "${USER_CONFIG_FILE}")
local PROXY
PROXY=$(readConfigKey "${1}" "${USER_CONFIG_FILE}")
while true; do
[ "${1}" = "global_proxy" ] && EG="http://192.168.1.1:7981/" || EG="https://mirror.ghproxy.com/"
DIALOG --title "$(TEXT "Settings")" \
@ -2803,10 +2800,11 @@ function changePassword() {
[ $? -ne 0 ] && return
DIALOG --title "$(TEXT "Settings")" \
--infobox "$(TEXT "Setting ...")" 20 100
local STRPASSWD="$(cat "${TMP_PATH}/resp")"
local STRPASSWD NEWPASSWD
STRPASSWD="$(cat "${TMP_PATH}/resp")"
# local NEWPASSWD="$(python3 -c "from passlib.hash import sha512_crypt;pw=\"${STRPASSWD:-rr}\";print(sha512_crypt.using(rounds=5000).hash(pw))")"
# local NEWPASSWD="$(echo "${STRPASSWD:-rr}" | mkpasswd -m sha512)"
local NEWPASSWD="$(openssl passwd -6 -salt $(openssl rand -hex 8) "${STRPASSWD:-rr}")"
NEWPASSWD="$(openssl passwd -6 -salt "$(openssl rand -hex 8)" "${STRPASSWD:-rr}")"
cp -pf /etc/shadow /etc/shadow-
sed -i "s|^root:[^:]*|root:${NEWPASSWD}|" /etc/shadow
@ -2838,7 +2836,7 @@ function changePassword() {
fi
if [ -n "$(ls -A "${RDXZ_PATH}" 2>/dev/null)" ] && [ -n "$(ls -A "${RDXZ_PATH}/etc" 2>/dev/null)" ]; then
local RDSIZE=$(du -sb ${RDXZ_PATH} 2>/dev/null | awk '{print $1}')
# local RDSIZE=$(du -sb ${RDXZ_PATH} 2>/dev/null | awk '{print $1}')
case "${INITRD_FORMAT}" in
*'x-cpio'*) (cd "${RDXZ_PATH}" && find . 2>/dev/null | cpio -o -H newc -R root:root >"${RR_RAMUSER_FILE}") >/dev/null 2>&1 ;;
*'x-xz'*) (cd "${RDXZ_PATH}" && find . 2>/dev/null | cpio -o -H newc -R root:root | xz -9 -C crc32 -c - >"${RR_RAMUSER_FILE}") >/dev/null 2>&1 ;;
@ -2863,7 +2861,7 @@ function changePassword() {
###############################################################################
# Change ports of TTYD/DUFS/HTTP
function changePorts() {
local MSG="$(TEXT "Please fill in a number between 0-65535: (Empty for default value.)")"
MSG="$(TEXT "Please fill in a number between 0-65535: (Empty for default value.)")"
unset HTTP_PORT DUFS_PORT TTYD_PORT
[ -f "/etc/rrorg.conf" ] && source "/etc/rrorg.conf" 2>/dev/null
local HTTP=${HTTP_PORT:-7080}
@ -2933,7 +2931,7 @@ function changePorts() {
cp -pf /etc/rrorg.conf ${RDXZ_PATH}/etc
fi
if [ -n "$(ls -A "${RDXZ_PATH}" 2>/dev/null)" ] && [ -n "$(ls -A "${RDXZ_PATH}/etc" 2>/dev/null)" ]; then
local RDSIZE=$(du -sb ${RDXZ_PATH} 2>/dev/null | awk '{print $1}')
# local RDSIZE=$(du -sb ${RDXZ_PATH} 2>/dev/null | awk '{print $1}')
case "${INITRD_FORMAT}" in
*'x-cpio'*) (cd "${RDXZ_PATH}" && find . 2>/dev/null | cpio -o -H newc -R root:root >"${RR_RAMUSER_FILE}") >/dev/null 2>&1 ;;
*'x-xz'*) (cd "${RDXZ_PATH}" && find . 2>/dev/null | cpio -o -H newc -R root:root | xz -9 -C crc32 -c - >"${RR_RAMUSER_FILE}") >/dev/null 2>&1 ;;
@ -3361,7 +3359,7 @@ function settingsMenu() {
else
createMicrocode
fi
NEXT="e"
NEXT="3"
;;
4)
changePassword
@ -3418,7 +3416,7 @@ function downloadExts() {
# TAG="$(curl -skL --connect-timeout 10 "${PROXY}${3}/tags" | pup 'a[class="Link--muted"] attr{href}' | grep ".zip" | head -1)"
TAG="$(curl -skL --connect-timeout 10 "${PROXY}${3}/tags" | grep "/refs/tags/.*\.zip" | sed -E 's/.*\/refs\/tags\/(.*)\.zip.*$/\1/' | sort -rV | head -1)"
else
TAG="$(curl -skL --connect-timeout 10 -w %{url_effective} -o /dev/null "${PROXY}${3}/releases/latest" | awk -F'/' '{print $NF}')"
TAG="$(curl -skL --connect-timeout 10 -w "%{url_effective}" -o /dev/null "${PROXY}${3}/releases/latest" | awk -F'/' '{print $NF}')"
fi
[ "${TAG:0:1}" = "v" ] && TAG="${TAG:1}"
if [ "${TAG:-latest}" = "latest" ]; then
@ -3481,9 +3479,9 @@ function downloadExts() {
}
rm -f "${LOG_FILE}"
if [ "${5}" = "-1" ]; then
__download $@ 2>&1
__download "$@" 2>&1
else
__download $@ 2>&1 | DIALOG --title "${T}" \
__download "$@" 2>&1 | DIALOG --title "${T}" \
--progressbox "$(TEXT "Downloading ...")" 20 100
fi
if [ -f "${LOG_FILE}" ]; then
@ -3581,7 +3579,7 @@ function updateRR() {
FSOLD=$(du -sm "/${VALUE}" 2>/dev/null | awk '{print $1}')
SIZENEW=$((${SIZENEW} + ${FSNEW:-0}))
SIZEOLD=$((${SIZEOLD} + ${FSOLD:-0}))
done <<<$(readConfigMap "replace" "${TMP_PATH}/update/update-list.yml")
done <<<"$(readConfigMap "replace" "${TMP_PATH}/update/update-list.yml")"
SIZESPL=$(df -m "${PART3_PATH}" 2>/dev/null | awk 'NR==2 {print $4}')
if [ ${SIZENEW:-0} -ge $((${SIZEOLD:-0} + ${SIZESPL:-0})) ]; then
@ -3606,7 +3604,7 @@ function updateRR() {
while read -r F; do
[ -f "${F}" ] && rm -f "${F}"
[ -d "${F}" ] && rm -rf "${F}"
done <<<$(readConfigArray "remove" "${TMP_PATH}/update/update-list.yml")
done <<<"$(readConfigArray "remove" "${TMP_PATH}/update/update-list.yml")"
while IFS=': ' read -r KEY VALUE; do
VALUE="${VALUE#/}" # Remove leading slash
VALUE="${VALUE%/}" # Remove trailing slash
@ -3625,7 +3623,7 @@ function updateRR() {
mkdir -p "$(dirname "/${VALUE}")"
cp -f "${TMP_PATH}/update/${VALUE}" "/${VALUE}"
fi
done <<<$(readConfigMap "replace" "${TMP_PATH}/update/update-list.yml")
done <<<"$(readConfigMap "replace" "${TMP_PATH}/update/update-list.yml")"
rm -rf "${TMP_PATH}/update"
touch ${PART1_PATH}/.upgraded
touch ${PART1_PATH}/.build
@ -3669,12 +3667,13 @@ function updateAddons() {
return 1
fi
for PKG in $(ls ${TMP_PATH}/update/*.addon 2>/dev/null); do
ADDON=$(basename ${PKG} .addon)
for F in ${TMP_PATH}/update/*.addon; do
[ ! -e "${F}" ] && continue
ADDON=$(basename "${F}" .addon)
rm -rf "${TMP_PATH}/update/${ADDON}"
mkdir -p "${TMP_PATH}/update/${ADDON}"
tar -xaf "${PKG}" -C "${TMP_PATH}/update/${ADDON}" >/dev/null 2>&1
rm -f "${PKG}"
tar -xaf "${F}" -C "${TMP_PATH}/update/${ADDON}" >/dev/null 2>&1
rm -f "${F}"
done
SIZENEW="$(du -sm "${TMP_PATH}/update" 2>/dev/null | awk '{print $1}')"
@ -3999,51 +3998,42 @@ function updateMenu() {
MSG+="$(TEXT "Upload rr-cks*.zip will update CKs.\n")"
DIALOG --title "$(TEXT "Update")" \
--msgbox "${MSG}" 0 0
EXTS=(update*.zip addons*.zip modules*.zip rp-lkms*.zip rr-cks*.zip)
TMP_UP_PATH="${TMP_PATH}/users"
USER_FILE=""
rm -rf "${TMP_UP_PATH}"
mkdir -p "${TMP_UP_PATH}"
pushd "${TMP_UP_PATH}" 2>/dev/null || return
rz -be
for F in $(ls -A 2>/dev/null); do
for I in ${EXTS[@]}; do
[ "${F}" = "${I}" ] && USER_FILE="${F}"
done
break
done
popd 2>/dev/null || return
(cd "${TMP_UP_PATH}" && rz -be) || true
USER_FILE="$(find "${TMP_UP_PATH}" -type f | head -1)"
if [ -z "${USER_FILE}" ]; then
DIALOG --title "$(TEXT "Update")" \
--msgbox "$(TEXT "Not a valid file, please try again!")" 0 0
else
case "${USER_FILE}" in
update*.zip)
*update*.zip)
rm -f ${TMP_PATH}/update*.zip
updateRR "${TMP_UP_PATH}/${USER_FILE}" "${SILENT}"
updateRR "${USER_FILE}" "${SILENT}"
;;
addons*.zip)
*addons*.zip)
rm -f ${TMP_PATH}/addons*.zip
updateAddons "${TMP_UP_PATH}/${USER_FILE}" "${SILENT}"
updateAddons "${USER_FILE}" "${SILENT}"
;;
modules*.zip)
*modules*.zip)
rm -f ${TMP_PATH}/modules*.zip
updateModules "${TMP_UP_PATH}/${USER_FILE}" "${SILENT}"
updateModules "${USER_FILE}" "${SILENT}"
;;
rp-lkms*.zip)
*rp-lkms*.zip)
rm -f ${TMP_PATH}/rp-lkms*.zip
updateLKMs "${TMP_UP_PATH}/${USER_FILE}" "${SILENT}"
updateLKMs "${USER_FILE}" "${SILENT}"
;;
rr-cks*.zip)
*rr-cks*.zip)
rm -f ${TMP_PATH}/rr-cks*.zip
updateCKs "${TMP_UP_PATH}/${USER_FILE}" "${SILENT}"
updateCKs "{USER_FILE}" "${SILENT}"
;;
*)
DIALOG --title "$(TEXT "Update")" \
--msgbox "$(TEXT "Not a valid file, please try again!")" 0 0
;;
esac
rm -f "${TMP_UP_PATH}/${USER_FILE}"
rm -rf "${TMP_UP_PATH}"
fi
;;
b)
@ -4123,7 +4113,7 @@ else
echo "b \"$(TEXT "Boot the loader")\""
fi
echo "h \"$(TEXT "Settings menu")\""
if [ 0$(du -sm ${PART3_PATH}/dl 2>/dev/null | awk '{printf $1}') -gt 1 ]; then
if [ "0$(du -sm ${PART3_PATH}/dl 2>/dev/null | awk '{printf $1}')" -gt 1 ]; then
echo "c \"$(TEXT "Clean disk cache")\""
fi
echo "p \"$(TEXT "Update menu")\""

View File

@ -1,9 +1,11 @@
#!/usr/bin/sh
#!/usr/bin/env sh
# This script is saved to /sbin/modprobe which is a so called UMH (user-mode-helper) for kmod (kernel/kmod.c)
# The kmod subsystem in the kernel is used to load modules from kernel. We exploit it a bit to load RP as soon as
# possible (which turns out to be via init/main.c => load_default_modules => load_default_elevator_module
# When the kernel is booted with "elevator=elevator" it will attempt to load a module "elevator-iosched"... and the rest
# should be obvious from the code below. DO NOT print anything here (kernel doesn't attach STDOUT)
for arg in "$@"; do
if [ "${arg}" = "elevator-iosched" ]; then
insmod /usr/lib/modules/rp.ko

View File

@ -1,4 +1,12 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
# shellcheck disable=SC2034
[ -z "${WORK_PATH}" ] || [ ! -d "${WORK_PATH}/include" ] && WORK_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
@ -53,7 +61,7 @@ mkdir -p "${RAMDISK_PATH}"
. "${RAMDISK_PATH}/etc/VERSION"
if [ -n "${PRODUCTVER}" ] && [ -n "${BUILDNUM}" ] && [ -n "${SMALLNUM}" ] &&
([ ! "${PRODUCTVER}" = "${majorversion}.${minorversion}" ] || [ ! "${BUILDNUM}" = "${buildnumber}" ] || [ ! "${SMALLNUM}" = "${smallfixnumber}" ]); then
([ ! "${PRODUCTVER}" = "${majorversion:-0}.${minorversion:-0}" ] || [ ! "${BUILDNUM}" = "${buildnumber:-0}" ] || [ ! "${SMALLNUM}" = "${smallfixnumber:-0}" ]); then
OLDVER="${PRODUCTVER}(${BUILDNUM}$([ ${SMALLNUM:-0} -ne 0 ] && echo "u${SMALLNUM}"))"
NEWVER="${majorversion}.${minorversion}(${buildnumber}$([ ${smallfixnumber:-0} -ne 0 ] && echo "u${smallfixnumber}"))"
echo -e "\033[A\n\033[1;32mBuild number changed from \033[1;31m${OLDVER}\033[1;32m to \033[1;31m${NEWVER}\033[0m"
@ -102,7 +110,8 @@ for PE in "${PATCHS[@]}"; do
RET=1
echo "Patching with ${PE}" >"${LOG_FILE}"
# ${PE} contains *, so double quotes cannot be added
for PF in $(ls ${WORK_PATH}/patch/${PE} 2>/dev/null); do
for PF in ${WORK_PATH}/patch/${PE}; do
[ ! -e "${PF}" ] && continue
echo "Patching with ${PF}" >>"${LOG_FILE}"
# busybox patch and gun patch have different processing methods and parameters.
(cd "${RAMDISK_PATH}" && busybox patch -p1 -i "${PF}") >>"${LOG_FILE}" 2>&1
@ -148,7 +157,7 @@ echo -n "."
installModules "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}" "${!MODULES[@]}" || exit 1
# Copying fake modprobe
[ $(echo "${KVER:-4}" | cut -d'.' -f1) -lt 5 ] && cp -f "${WORK_PATH}/patch/iosched-trampoline.sh" "${RAMDISK_PATH}/usr/sbin/modprobe"
[ "$(echo "${KVER:-4}" | cut -d'.' -f1)" -lt 5 ] && cp -f "${WORK_PATH}/patch/iosched-trampoline.sh" "${RAMDISK_PATH}/usr/sbin/modprobe"
# Copying LKM to /usr/lib/modules
gzip -dc "${LKMS_PATH}/rp-${PLATFORM}-${KPRE:+${KPRE}-}${KVER}-${LKM}.ko.gz" >"${RAMDISK_PATH}/usr/lib/modules/rp.ko" 2>"${LOG_FILE}" || exit 1
@ -196,7 +205,7 @@ echo "inetd" >>"${RAMDISK_PATH}/addons/addons.sh"
echo -n "."
echo "Modify files" >"${LOG_FILE}"
# Remove function from scripts
[ "2" = "${BUILDNUM:0:1}" ] && sed -i 's/function //g' $(find "${RAMDISK_PATH}/addons/" -type f -name "*.sh")
[ "2" = "${BUILDNUM:0:1}" ] && find "${RAMDISK_PATH}/addons/" -type f -name "*.sh" -exec sed -i 's/function //g' {} \;
# Build modules dependencies
# ${WORK_PATH}/depmod -a -b ${RAMDISK_PATH} 2>/dev/null # addon eudev will do this
@ -245,8 +254,10 @@ fi
# Call user patch scripts
echo -n "."
for F in $(ls -1 "${SCRIPTS_PATH}/"*.sh 2>/dev/null); do
for F in ${SCRIPTS_PATH}/*.sh; do
[ ! -e "${F}" ] && continue
echo "Calling ${F}" >"${LOG_FILE}"
# shellcheck source=/dev/null
. "${F}" >>"${LOG_FILE}" 2>&1 || exit 1
done

View File

@ -1,4 +1,10 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
# Based on code and ideas from @jumkey
[ -z "${WORK_PATH}" ] || [ ! -d "${WORK_PATH}/include" ] && WORK_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
@ -12,7 +18,7 @@ calculate_run_size() {
return 1
fi
read -r sizeA offsetA sizeB offsetB <<<$(echo ${OUT} | awk '{printf "%d %d %d %d", strtonum($1), strtonum($2), strtonum($3), strtonum($4)}')
read -r sizeA offsetA sizeB offsetB <<<"$(echo ${OUT} | awk '{printf "%d %d %d %d", strtonum($1), strtonum($2), strtonum($3), strtonum($4)}')"
runSize=$((offsetA + sizeA + sizeB))
@ -38,23 +44,23 @@ calculate_run_size() {
# Usage: size_append FILE [FILE2] [FILEn]...
# Output: LE HEX with size of file in bytes (to STDOUT)
file_size_le() {
printf $(
printf "$(
local dec_size=0
for F in "$@"; do dec_size=$((dec_size + $(stat -c "%s" "${F}"))); done
printf "%08x\n" "${dec_size}" | sed 's/\(..\)/\1 /g' | {
read -r ch0 ch1 ch2 ch3
for ch in "${ch3}" "${ch2}" "${ch1}" "${ch0}"; do printf '%s%03o' '\' "$((0x${ch}))"; done
}
)
)"
}
size_le() {
printf $(
printf "$(
printf "%08x\n" "${@}" | sed 's/\(..\)/\1 /g' | {
read -r ch0 ch1 ch2 ch3
for ch in "${ch3}" "${ch2}" "${ch1}" "${ch0}"; do printf '%s%03o' '\' "$((0x${ch}))"; done
}
)
)"
}
VMLINUX_MOD=${1}

View File

@ -1,4 +1,10 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
[ -z "${WORK_PATH}" ] || [ ! -d "${WORK_PATH}/include" ] && WORK_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"

View File

@ -37,14 +37,14 @@ function create() {
sudo apt update
sudo apt install -y locales busybox dialog gettext sed gawk jq curl
sudo apt install -y python-is-python3 python3-pip libelf-dev qemu-utils cpio xz-utils lz4 lzma bzip2 gzip zstd
sudo apt install -y python-is-python3 python3-pip libelf-dev qemu-utils dosfstools cpio xz-utils lz4 lzma bzip2 gzip zstd
# sudo snap install yq
if ! command -v yq &>/dev/null || ! yq --version 2>/dev/null | grep -q "v4."; then
sudo curl -kL https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -o /usr/bin/yq && sudo chmod a+x /usr/bin/yq
fi
# Backup the original python3 executable.
sudo mv -f "$(realpath $(which python3))/EXTERNALLY-MANAGED" "$(realpath $(which python3))/EXTERNALLY-MANAGED.bak" 2>/dev/null || true
sudo mv -f "$(realpath "$(which python3)")/EXTERNALLY-MANAGED" "$(realpath "$(which python3)")/EXTERNALLY-MANAGED.bak" 2>/dev/null || true
sudo pip3 install -U click requests requests-toolbelt qrcode[pil] beautifulsoup4
sudo locale-gen ar_SA.UTF-8 de_DE.UTF-8 en_US.UTF-8 es_ES.UTF-8 fr_FR.UTF-8 ja_JP.UTF-8 ko_KR.UTF-8 ru_RU.UTF-8 th_TH.UTF-8 tr_TR.UTF-8 uk_UA.UTF-8 vi_VN.UTF-8 zh_CN.UTF-8 zh_HK.UTF-8 zh_TW.UTF-8
@ -52,6 +52,11 @@ function create() {
LOOPX=$(sudo losetup -f)
sudo losetup -P "${LOOPX}" "${RRIMGPATH}"
# Check partitions and ignore errors
fsck.vfat -aw "${LOOPX}p1" >/dev/null 2>&1 || true
fsck.ext2 -p "${LOOPX}p2" >/dev/null 2>&1 || true
fsck.ext4 -p "${LOOPX}p3" >/dev/null 2>&1 || true
echo "Mounting image file"
for i in {1..3}; do
rm -rf "/tmp/mnt/p${i}"
@ -107,11 +112,11 @@ function init() {
exit 1
fi
. "$(dirname "${BASH_SOURCE[0]}")/rr.env"
pushd "${CHROOT_PATH}/initrd/opt/rr" >/dev/null
pushd "${CHROOT_PATH}/initrd/opt/rr" || exit 1
echo "init"
./init.sh
local RET=$?
popd >/dev/null
popd || exit 1
[ ${RET} -ne 0 ] && echo "Failed." || echo "Success."
exit ${RET}
}
@ -123,7 +128,7 @@ function config() {
fi
. "$(dirname "${BASH_SOURCE[0]}")/rr.env"
local RET=1
pushd "${CHROOT_PATH}/initrd/opt/rr" >/dev/null
pushd "${CHROOT_PATH}/initrd/opt/rr" || exit 1
while true; do
if [ -z "${1}" ]; then
echo "menu"
@ -138,7 +143,7 @@ function config() {
fi
break
done
popd >/dev/null
popd || exit 1
[ ${RET} -ne 0 ] && echo "Failed." || echo "Success."
exit ${RET}
}
@ -150,7 +155,7 @@ function build() {
fi
. "$(dirname "${BASH_SOURCE[0]}")/rr.env"
local RET=1
pushd "${CHROOT_PATH}/initrd/opt/rr" >/dev/null
pushd "${CHROOT_PATH}/initrd/opt/rr" || exit 1
while true; do
echo "build"
./menu.sh make -1 || break
@ -159,7 +164,7 @@ function build() {
RET=0
break
done
popd >/dev/null
popd || exit 1
[ ${RET} -ne 0 ] && echo "Failed." || echo "Success."
exit ${RET}
}
@ -181,6 +186,11 @@ function pack() {
LOOPX=$(sudo losetup -f)
sudo losetup -P "${LOOPX}" "${RRIMGPATH}"
# Check partitions and ignore errors
fsck.vfat -aw "${LOOPX}p1" >/dev/null 2>&1 || true
fsck.ext2 -p "${LOOPX}p2" >/dev/null 2>&1 || true
fsck.ext4 -p "${LOOPX}p3" >/dev/null 2>&1 || true
echo "Mounting image file"
for i in {1..3}; do
rm -rf "/tmp/mnt/p${i}"
@ -210,4 +220,4 @@ function pack() {
exit 0
}
$@
"$@"

View File

@ -21,7 +21,7 @@ function convertpo2mo() {
# Use msgfmt command to compile the .po file into a binary .mo file
echo "msgfmt ${P} to ${P/.po/.mo}"
msgfmt "${P}" -o "${P/.po/.mo}"
done <<<$(find "${DEST_PATH}" -type f -name 'rr.po')
done <<<"$(find "${DEST_PATH}" -type f -name 'rr.po')"
echo "Convert po2mo end"
}
@ -37,7 +37,8 @@ function getExtractor() {
# global.synologydownload.com, global.download.synology.com, cndl.synology.cn
local PAT_URL="https://global.synologydownload.com/download/DSM/release/7.0.1/42218/DSM_DS3622xs%2B_42218.pat"
local PAT_FILE="DSM_DS3622xs+_42218.pat"
local STATUS=$(curl -#L -w "%{http_code}" "${PAT_URL}" -o "${CACHE_DIR}/${PAT_FILE}")
local STATUS
STATUS=$(curl -#L -w "%{http_code}" "${PAT_URL}" -o "${CACHE_DIR}/${PAT_FILE}")
if [ $? -ne 0 ] || [ "${STATUS:-0}" -ne 200 ]; then
echo "[E] DSM_DS3622xs%2B_42218.pat download error!"
rm -rf "${CACHE_DIR}"
@ -84,11 +85,12 @@ function getBuildroot() {
fi
while read -r ID NAME; do
if [ "${NAME}" = "buildroot-${TAG}.zip" ]; then
local STATUS
STATUS=$(curl -kL -w "%{http_code}" -H "Authorization: token ${TOKEN}" -H "Accept: application/octet-stream" "${REPO}/rr-buildroot/releases/assets/${ID}" -o "${CACHE_FILE}")
echo "TAG=${TAG}; Status=${STATUS}"
[ ${STATUS:-0} -ne 200 ] && exit 1
fi
done <<<$(curl -skL -H "Authorization: Bearer ${TOKEN}" "${REPO}/rr-buildroot/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"')
done <<<"$(curl -skL -H "Authorization: Bearer ${TOKEN}" "${REPO}/rr-buildroot/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"')"
# Unzip Buildroot
rm -rf "${CACHE_DIR}"
mkdir -p "${CACHE_DIR}"
@ -117,11 +119,12 @@ function getCKs() {
fi
while read -r ID NAME; do
if [ "${NAME}" = "rr-cks-${TAG}.zip" ]; then
local STATUS
STATUS=$(curl -kL -w "%{http_code}" -H "Authorization: token ${TOKEN}" -H "Accept: application/octet-stream" "${REPO}/rr-cks/releases/assets/${ID}" -o "${CACHE_FILE}")
echo "TAG=${TAG}; Status=${STATUS}"
[ ${STATUS:-0} -ne 200 ] && exit 1
fi
done <<<$(curl -skL -H "Authorization: Bearer ${TOKEN}" "${REPO}/rr-cks/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"')
done <<<"$(curl -skL -H "Authorization: Bearer ${TOKEN}" "${REPO}/rr-cks/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"')"
[ ! -f "${CACHE_FILE}" ] && exit 1
# Unzip CKs
rm -rf "${DEST_PATH}"
@ -147,11 +150,12 @@ function getLKMs() {
fi
while read -r ID NAME; do
if [ "${NAME}" = "rp-lkms-${TAG}.zip" ]; then
local STATUS
STATUS=$(curl -kL -w "%{http_code}" -H "Authorization: token ${TOKEN}" -H "Accept: application/octet-stream" "${REPO}/rr-lkms/releases/assets/${ID}" -o "${CACHE_FILE}")
echo "TAG=${TAG}; Status=${STATUS}"
[ ${STATUS:-0} -ne 200 ] && exit 1
fi
done <<<$(curl -skL -H "Authorization: Bearer ${TOKEN}" "${REPO}/rr-lkms/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"')
done <<<"$(curl -skL -H "Authorization: Bearer ${TOKEN}" "${REPO}/rr-lkms/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"')"
[ ! -f "${CACHE_FILE}" ] && exit 1
# Unzip LKMs
rm -rf "${DEST_PATH}"
@ -177,11 +181,12 @@ function getAddons() {
fi
while read -r ID NAME; do
if [ "${NAME}" = "addons-${TAG}.zip" ]; then
local STATUS
STATUS=$(curl -kL -w "%{http_code}" -H "Authorization: token ${TOKEN}" -H "Accept: application/octet-stream" "${REPO}/rr-addons/releases/assets/${ID}" -o "${CACHE_FILE}")
echo "TAG=${TAG}; Status=${STATUS}"
[ ${STATUS:-0} -ne 200 ] && exit 1
fi
done <<<$(curl -skL -H "Authorization: Bearer ${TOKEN}" "${REPO}/rr-addons/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"')
done <<<"$(curl -skL -H "Authorization: Bearer ${TOKEN}" "${REPO}/rr-addons/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"')"
[ ! -f "${CACHE_FILE}" ] && exit 1
rm -rf "${DEST_PATH}"
mkdir -p "${DEST_PATH}"
@ -191,11 +196,15 @@ function getAddons() {
unzip "${CACHE_FILE}" -d "${CACHE_DIR}"
echo "Installing addons to ${DEST_PATH}"
[ -f "/tmp/addons/VERSION" ] && cp -f "/tmp/addons/VERSION" "${DEST_PATH}/"
for PKG in "${CACHE_DIR}"/*.addon; do
ADDON=$(basename "${PKG}" .addon)
for F in ${CACHE_DIR}/*.addon; do
[ ! -e "${F}" ] && continue
ADDON=$(basename "${F}" .addon)
# shellcheck disable=SC2115
rm -rf "${DEST_PATH}/${ADDON}"
mkdir -p "${DEST_PATH}/${ADDON}"
echo "Extracting ${PKG} to ${DEST_PATH}/${ADDON}"
tar -xaf "${PKG}" -C "${DEST_PATH}/${ADDON}"
echo "Extracting ${F} to ${DEST_PATH}/${ADDON}"
tar -xaf "${F}" -C "${DEST_PATH}/${ADDON}"
rm -f "${F}"
done
rm -rf "${CACHE_DIR}"
rm -f "${CACHE_FILE}"
@ -218,11 +227,12 @@ function getModules() {
fi
while read -r ID NAME; do
if [ "${NAME}" = "modules-${TAG}.zip" ]; then
local STATUS
STATUS=$(curl -kL -w "%{http_code}" -H "Authorization: token ${TOKEN}" -H "Accept: application/octet-stream" "${REPO}/rr-modules/releases/assets/${ID}" -o "${CACHE_FILE}")
echo "TAG=${TAG}; Status=${STATUS}"
[ ${STATUS:-0} -ne 200 ] && exit 1
fi
done <<<$(curl -skL -H "Authorization: Bearer ${TOKEN}" "${REPO}/rr-modules/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"')
done <<<"$(curl -skL -H "Authorization: Bearer ${TOKEN}" "${REPO}/rr-modules/releases/tags/${TAG}" | jq -r '.assets[] | "\(.id) \(.name)"')"
[ ! -f "${CACHE_FILE}" ] && exit 1
# Unzip Modules
rm -rf "${DEST_PATH}"
@ -250,7 +260,8 @@ function repackInitrd() {
local RDXZ_PATH="rdxz_tmp"
mkdir -p "${RDXZ_PATH}"
local INITRD_FORMAT=$(file -b --mime-type "${INITRD_FILE}")
local INITRD_FORMAT
INITRD_FORMAT=$(file -b --mime-type "${INITRD_FILE}")
case "${INITRD_FORMAT}" in
*'x-cpio'*) (cd "${RDXZ_PATH}" && sudo cpio -idm <"${INITRD_FILE}") >/dev/null 2>&1 ;;
@ -265,7 +276,7 @@ function repackInitrd() {
sudo cp -rf "${PLUGIN_PATH}/"* "${RDXZ_PATH}/"
[ -f "${OUTPUT_PATH}" ] && rm -rf "${OUTPUT_PATH}"
# shellcheck disable=SC2024
case "${INITRD_FORMAT}" in
*'x-cpio'*) (cd "${RDXZ_PATH}" && sudo find . 2>/dev/null | sudo cpio -o -H newc -R root:root >"${OUTPUT_PATH}") >/dev/null 2>&1 ;;
*'x-xz'*) (cd "${RDXZ_PATH}" && sudo find . 2>/dev/null | sudo cpio -o -H newc -R root:root | xz -9 -C crc32 -c - >"${OUTPUT_PATH}") >/dev/null 2>&1 ;;
@ -303,19 +314,20 @@ function resizeImg() {
sudo truncate -s ${SIZE}M "${OUTPUT_FILE}"
echo -e "d\n\nn\n\n\n\n\nn\nw" | sudo fdisk "${OUTPUT_FILE}" >/dev/null 2>&1
local LOOPX=$(sudo losetup -f)
sudo losetup -P ${LOOPX} "${OUTPUT_FILE}"
sudo e2fsck -fp $(ls ${LOOPX}* 2>/dev/null | sort -n | tail -1)
sudo resize2fs $(ls ${LOOPX}* 2>/dev/null | sort -n | tail -1)
sudo losetup -d ${LOOPX}
local LOOPX
LOOPX=$(sudo losetup -f)
sudo losetup -P "${LOOPX}" "${OUTPUT_FILE}"
sudo e2fsck -fp "$(ls ${LOOPX}* 2>/dev/null | sort -n | tail -1)"
sudo resize2fs "$(ls ${LOOPX}* 2>/dev/null | sort -n | tail -1)"
sudo losetup -d "${LOOPX}"
}
# createvmx
# $1 bootloader file
# $2 vmx name
function createvmx() {
BLIMAGE=${1}
VMNAME=${2}
local BLIMAGE=${1}
local VMNAME=${2}
if ! command -v qemu-img &>/dev/null; then
sudo apt install -y qemu-utils
@ -397,10 +409,10 @@ _EOF_
function convertvmx() {
local BLIMAGE=${1}
local VMXPATH=${2}
local VMNAME
BLIMAGE="$(realpath "${BLIMAGE}")"
VMXPATH="$(realpath "${VMXPATH}")"
local VMNAME="$(basename "${VMXPATH}" .vmx)"
VMNAME="$(basename "${VMXPATH}" .vmx)"
createvmx "${BLIMAGE}" "${VMNAME}"
@ -414,10 +426,11 @@ function convertvmx() {
function convertova() {
local BLIMAGE=${1}
local OVAPATH=${2}
local VMNAME
BLIMAGE="$(realpath "${BLIMAGE}")"
OVAPATH="$(realpath "${OVAPATH}")"
local VMNAME="$(basename "${OVAPATH}" .ova)"
VMNAME="$(basename "${OVAPATH}" .ova)"
createvmx "${BLIMAGE}" "${VMNAME}"

View File

@ -7,7 +7,7 @@
#
# sudo apt update
# sudo apt install -y locales busybox dialog gettext sed gawk jq curl
# sudo apt install -y python-is-python3 python3-pip libelf-dev qemu-utils cpio xz-utils lz4 lzma bzip2 gzip zstd
# sudo apt install -y python-is-python3 python3-pip libelf-dev qemu-utils dosfstools cpio xz-utils lz4 lzma bzip2 gzip zstd
# # sudo snap install yq
# if ! command -v yq &>/dev/null || ! yq --version 2>/dev/null | grep -q "v4."; then
# sudo curl -kL https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -o /usr/bin/yq && sudo chmod a+x /usr/bin/yq
@ -42,10 +42,12 @@ convertpo2mo "files/initrd/opt/rr/lang"
repackInitrd "files/mnt/p3/initrd-rr" "files/initrd"
if [ -n "${1}" ]; then
LOADER_DISK="LOCALBUILD"
CHROOT_PATH="$(realpath files)"
export LOADER_DISK="LOCALBUILD"
export CHROOT_PATH="$(realpath files)"
export CHROOT_PATH="${CHROOT_PATH}"
(
cd "${CHROOT_PATH}/initrd/opt/rr"
cd "${CHROOT_PATH}/initrd/opt/rr" || exit 1
./init.sh
./menu.sh modelMenu "${1}"
./menu.sh productversMenu "${2:-7.2}"
@ -61,6 +63,11 @@ fdisk -l "${IMAGE_FILE}"
LOOPX=$(sudo losetup -f)
sudo losetup -P "${LOOPX}" "${IMAGE_FILE}"
# Check partitions and ignore errors
fsck.vfat -aw "${LOOPX}p1" >/dev/null 2>&1 || true
fsck.ext2 -p "${LOOPX}p2" >/dev/null 2>&1 || true
fsck.ext4 -p "${LOOPX}p3" >/dev/null 2>&1 || true
for i in {1..3}; do
[ ! -d "files/mnt/p${i}" ] && continue
@ -103,8 +110,8 @@ while read -r F; do
zip -9j "update.zip" "${FTGZ}"
rm -f "${FTGZ}"
else
(cd $(dirname "${F}") && sha256sum $(basename "${F}")) >>sha256sum
(cd "$(dirname "${F}")" && sha256sum "$(basename "${F}")") >>sha256sum
zip -9j "update.zip" "${F}"
fi
done <<<$(yq '.replace | explode(.) | to_entries | map([.key])[] | .[]' update-list.yml)
done <<<"$(yq '.replace | explode(.) | to_entries | map([.key])[] | .[]' update-list.yml)"
zip -9j "update.zip" sha256sum