Compare commits

..

No commits in common. "7c0e5ba3e3bab40a42ce1a1a060b14df61ba7b14" and "e67ce76a8829e587fe0c9c34a11cdce68c2fe131" have entirely different histories.

21 changed files with 396 additions and 535 deletions

View File

@ -1,108 +1,108 @@
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
name: Data
on:
release:
types:
- created
workflow_dispatch:
inputs:
push:
description: "push"
default: false
type: boolean
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@main
with:
ref: main
- name: Init Env
run: |
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
sudo timedatectl set-timezone "Asia/Shanghai"
- name: Delay
run: |
echo "Delaying for 1 minutes..."
sleep 60
- name: Get Release RR
run: |
REPO="${{ github.server_url }}/${{ github.repository }}"
PRERELEASE="true"
TAG=""
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}')"
fi
[ "${TAG:0:1}" = "v" ] && TAG="${TAG:1}"
rm -f rr-${TAG}.img.zip
STATUS=$(curl -kL --connect-timeout 10 -w "%{http_code}" "${REPO}/releases/download/${TAG}/rr-${TAG}.img.zip" -o "rr-${TAG}.img.zip")
if [ $? -ne 0 ] || [ ${STATUS:-0} -ne 200 ]; then
echo "Download failed"
exit 1
fi
unzip rr-${TAG}.img.zip -d "rr"
export TERM=xterm
sudo ./localbuild.sh create rr/ws rr/rr.img
if [ $? -ne 0 ]; then
echo "create failed"
exit 1
fi
- name: Get data
run: |
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 build-essential libtool pkgconf libzstd-dev liblzma-dev libssl-dev # kmodule dependencies
# Backup the original python3 executable.
sudo mv -f "$(realpath $(which python3))/EXTERNALLY-MANAGED" "$(realpath $(which python3))/EXTERNALLY-MANAGED.bak" 2>/dev/null || true
sudo pip3 install -U -r scripts/requirements.txt
python3 scripts/func.py getmodels -w "rr/ws/initrd" -j "docs/models.json" -x "docs/models.xlsx"
python3 scripts/func.py getaddons -w "rr/ws" -j "docs/addons.json" -x "docs/addons.xlsx"
python3 scripts/func.py getmodules -w "rr/ws" -j "docs/modules.json" -x "docs/modules.xlsx"
python3 scripts/func.py getpats -w "rr/ws/initrd" -j "docs/pats.json" -x "docs/pats.xlsx"
- name: Upload to Artifacts
if: success()
uses: actions/upload-artifact@v4
with:
name: docs
path: |
docs/*.json
docs/*.xlsx
retention-days: 5
- name: Check and Push
if: success() && (inputs.push == true || github.event.action == 'created')
run: |
echo "Git push ..."
# git checkout main
git pull
status=$(git status -s | grep -E "docs" | awk '{printf " %s", $2}')
if [ -n "${status}" ]; then
git add ${status}
git commit -m "update $(date +%Y-%m-%d" "%H:%M:%S)"
git push -f
fi
#
# Copyright (C) 2022 Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
name: Data
on:
release:
types:
- created
workflow_dispatch:
inputs:
push:
description: "push"
default: false
type: boolean
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@main
with:
ref: main
- name: Init Env
run: |
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
sudo timedatectl set-timezone "Asia/Shanghai"
- name: Delay
run: |
echo "Delaying for 1 minutes..."
sleep 60
- name: Get Release RR
run: |
REPO="${{ github.server_url }}/${{ github.repository }}"
PRERELEASE="true"
TAG=""
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}')"
fi
[ "${TAG:0:1}" = "v" ] && TAG="${TAG:1}"
rm -f rr-${TAG}.img.zip
STATUS=$(curl -kL --connect-timeout 10 -w "%{http_code}" "${REPO}/releases/download/${TAG}/rr-${TAG}.img.zip" -o "rr-${TAG}.img.zip")
if [ $? -ne 0 ] || [ ${STATUS:-0} -ne 200 ]; then
echo "Download failed"
exit 1
fi
unzip rr-${TAG}.img.zip -d "rr"
export TERM=xterm
sudo ./localbuild.sh create rr/ws rr/rr.img
if [ $? -ne 0 ]; then
echo "create failed"
exit 1
fi
- name: Get data
run: |
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 build-essential libtool pkgconf libzstd-dev liblzma-dev libssl-dev # kmodule dependencies
# Backup the original python3 executable.
sudo mv -f "$(realpath $(which python3))/EXTERNALLY-MANAGED" "$(realpath $(which python3))/EXTERNALLY-MANAGED.bak" 2>/dev/null || true
sudo pip3 install -U -r scripts/requirements.txt
python3 scripts/func.py getmodels -w "rr/ws/initrd" -j "docs/models.json" -x "docs/models.xlsx"
python3 scripts/func.py getaddons -w "rr/ws" -j "docs/addons.json" -x "docs/addons.xlsx"
python3 scripts/func.py getmodules -w "rr/ws" -j "docs/modules.json" -x "docs/modules.xlsx"
python3 scripts/func.py getpats -w "rr/ws/initrd" -j "docs/pats.json" -x "docs/pats.xlsx"
- name: Upload to Artifacts
if: success()
uses: actions/upload-artifact@v4
with:
name: docs
path: |
docs/*.json
docs/*.xlsx
retention-days: 5
- name: Check and Push
if: success() && (inputs.push == true || github.event.action == 'created')
run: |
echo "Git push ..."
# git checkout main
git pull
status=$(git status -s | grep -E "docs" | awk '{printf " %s", $2}')
if [ -n "${status}" ]; then
git add ${status}
git commit -m "update $(date +%Y-%m-%d" "%H:%M:%S)"
git push -f
fi

View File

@ -159,23 +159,20 @@ jobs:
}
function readConfigKey() {
local result
result=$(sudo yq eval ".${1} | explode(.)" "${2}" 2>/dev/null)
local 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 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}"
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}"
}
REPO="${{ github.server_url }}/${{ github.repository }}"
@ -187,7 +184,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
@ -286,33 +283,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
@ -363,4 +360,4 @@ jobs:
RR-${{ env.model }} build failed, please try again.
> ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
----
emoji: confused
emoji: confused

View File

@ -1,12 +1,4 @@
#!/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)"
@ -43,13 +35,12 @@ printf "\033[1;33m%*s\033[0m\n" $(((${#BTITLE} + ${COLUMNS}) / 2)) "${BTITLE}"
if [ -f ${PART1_PATH}/.upgraded ]; then
MODEL="$(readConfigKey "model" "${USER_CONFIG_FILE}")"
PLATFORM="$(readConfigKey "platform" "${USER_CONFIG_FILE}")"
if [ -n "${MODEL}" ] && [ -n "${PLATFORM}" ]; then
if [ -n "${MODEL}" ]; then
printf "\033[1;43m%s\033[0m\n" "$(TEXT "Reconfigure after upgrade ...")"
PRODUCTVER="$(readConfigKey "productver" "${USER_CONFIG_FILE}")"
PATURL="$(readConfigKey "paturl" "${USER_CONFIG_FILE}")"
PATSUM="$(readConfigKey "patsum" "${USER_CONFIG_FILE}")"
./menu.sh modelMenu "${MODEL}" "${PLATFORM}" || {
./menu.sh modelMenu "${MODEL}" || {
echo -e "$(TEXT "Reconfiguration failed!")"
exit 1
}
@ -122,7 +113,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
@ -166,10 +157,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}")"
@ -258,8 +249,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}"
@ -268,11 +259,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=""
@ -281,7 +272,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
@ -342,7 +333,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="$(find /sys/class/net/ -mindepth 1 -maxdepth 1 ! -name lo -exec basename {} \; | sort)"
ETHX=$(ls /sys/class/net/ 2>/dev/null | grep -v lo) || true
printf "$(TEXT "Detected %s network cards.\n")" "$(echo "${ETHX}" | wc -w)"
printf "$(TEXT "Checking Connect.")"
COUNT=0
@ -351,7 +342,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
@ -369,19 +360,19 @@ else
printf "$(TEXT "Waiting IP.\n")"
for N in ${ETHX}; do
COUNT=0
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)"
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)
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
@ -413,16 +404,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
@ -437,9 +428,9 @@ else
done
# Disconnect wireless
lsmod | grep -q iwlwifi && for F in /sys/class/net/wlan*; do [ ! -e "${F}" ] && continue; connectwlanif "$(basename "${F}")" 0 2>/dev/null; done
lsmod | grep -q iwlwifi && for N in $(ls /sys/class/net/ 2>/dev/null | grep wlan); do connectwlanif "${N}" 0 2>/dev/null; done
# Unload all network drivers
# for F in $(realpath /sys/class/net/*/device/driver); do [ ! -e "${F}" ] && continue; rmmod -f "$(basename ${F})" 2>/dev/null || true; done
# for D in $(realpath /sys/class/net/*/device/driver); do rmmod -f "$(basename ${D})" 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,10 +1,4 @@
#!/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,10 +1,5 @@
#!/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.
#
@ -19,7 +14,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))

Binary file not shown.

View File

@ -1,13 +1,3 @@
#!/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
@ -29,7 +19,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,11 +1,3 @@
#!/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
@ -30,8 +22,7 @@ function writeConfigKey() {
# 2 - Path of yaml config file
# Return Value
function readConfigKey() {
local result
result=$(yq eval ".${1} | explode(.)" "${2}" 2>/dev/null)
local result=$(yq eval ".${1} | explode(.)" "${2}" 2>/dev/null)
[ "${result}" = "null" ] && echo "" || echo "${result}"
}
@ -42,15 +33,13 @@ 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 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}"
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}"
}
###############################################################################

View File

@ -1,13 +1,3 @@
#!/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,11 +1,3 @@
#!/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"
@ -19,7 +11,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
@ -44,7 +36,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
}
@ -84,6 +76,7 @@ function randomhex() {
printf "%02X" $((RANDOM % 255 + 1))
}
###############################################################################
# Generate a random digit (0-9A-Z)
function genRandomDigit() {
@ -209,7 +202,7 @@ function _set_conf_kv() {
# Add if doesn't exist
echo "${1}=\"${2}\"" >>"${3}"
return 0
return $?
}
###############################################################################
@ -229,38 +222,36 @@ function _get_fastest() {
speedlist+="${I} ${speed:-999}\n" # Assign default value 999 if speed is empty
done
fi
local fastest
fastest="$(echo -e "${speedlist}" | tr -s '\n' | awk '$2 != "999"' | sort -k2n | head -1)"
local 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() {
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"
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"
done
ETHLISTTMPM=""
ETHLISTTMPB="$(echo -e "${ETHLIST}" | sort)"
local ETHLISTTMPM=""
local ETHLISTTMPB="$(echo -e "${ETHLIST}" | sort)"
if [ -n "${1}" ]; then
MACS="$(echo "${1}" | sed 's/://g; s/,/ /g; s/.*/\L&/')"
local 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 '^$')"
ETHSEQ="$(echo -e "${ETHLIST}" | awk '{print $3}' | sed 's/eth//g')"
ETHNUM="$(echo -e "${ETHLIST}" | wc -l)"
local ETHSEQ="$(echo -e "${ETHLIST}" | awk '{print $3}' | sed 's/eth//g')"
local ETHNUM="$(echo -e "${ETHLIST}" | wc -l)"
# echo "${ETHSEQ}"
# sort
@ -316,14 +307,13 @@ function getIP() {
# 1 - model
function getLogo() {
local MODEL="${1}"
local fastest
local STATUS
rm -f "${PART3_PATH}/logo.png"
local fastest="$(_get_fastest "www.synology.com" "www.synology.cn")"
# [ $? -ne 0 ] && return 1
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")
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"
return 1
fi
convert -rotate 180 "${PART3_PATH}/logo.png" "${PART3_PATH}/logo.png" 2>/dev/null
@ -380,10 +370,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
VT_D_ENABLED=$(rdmsr 0x3a 2>/dev/null)
local 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
IOMMU_ENABLED=$(rdmsr 0xC0010114 2>/dev/null)
local IOMMU_ENABLED=$(rdmsr 0xC0010114 2>/dev/null)
[ "$((${IOMMU_ENABLED:-0x0} & 0x1))" -eq $((0x1)) ] && return 0
else
return 1
@ -430,8 +420,7 @@ function connectwlanif() {
rm -f "/var/run/wpa_supplicant.pid.${1}"
fi
else
local CONF
CONF="$([ -f "${PART1_PATH}/wpa_supplicant.conf" ] && echo "${PART1_PATH}/wpa_supplicant.conf" || echo "")"
local 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,18 +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)"
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" ] && LC_ALL="$(cat "${PART1_PATH}/.locale")" && export LC_ALL="${LC_ALL}"
[ -f "${PART1_PATH}/.locale" ] && export LC_ALL="$(cat "${PART1_PATH}/.locale")"
if [ -f "${PART1_PATH}/.timezone" ]; then
TIMEZONE="$(cat "${PART1_PATH}/.timezone")"

View File

@ -1,11 +1,3 @@
#!/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
@ -13,8 +5,7 @@
function unpackModules() {
local PLATFORM=${1}
local PKVER=${2}
local KERNEL
KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
local KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
rm -rf "${TMP_PATH}/modules"
mkdir -p "${TMP_PATH}/modules"
@ -32,8 +23,7 @@ function unpackModules() {
function packagModules() {
local PLATFORM=${1}
local PKVER=${2}
local KERNEL
KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
local KERNEL="$(readConfigKey "kernel" "${USER_CONFIG_FILE}")"
if [ "${KERNEL}" = "custom" ]; then
tar -zcf "${CKS_PATH}/modules-${PLATFORM}-${PKVER}.tgz" -C "${TMP_PATH}/modules" .
@ -56,12 +46,10 @@ function getAllModules() {
unpackModules "${PLATFORM}" "${PKVER}"
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}')
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}')
[ -z "${DESC}" ] && DESC="${X}"
echo "${M} \"${DESC}\""
done
@ -77,23 +65,21 @@ 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}"
ODP="$(readConfigKey "odp" "${USER_CONFIG_FILE}")"
for F in ${TMP_PATH}/modules/*.ko; do
[ ! -e "${F}" ] && continue
M=$(basename "${F}")
local ODP="$(readConfigKey "odp" "${USER_CONFIG_FILE}")"
for F in $(ls "${TMP_PATH}/modules/"*.ko 2>/dev/null); do
local M=$(basename "${F}")
[ "${ODP}" = "true" ] && [ -f "${RAMDISK_PATH}/usr/lib/modules/${M}" ] && continue
if echo "${MLIST}" | grep -wq "$(basename "${M}" .ko)"; then
if echo "${MLIST}" | grep -wq "${M:0:-3}"; 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}"
@ -101,7 +87,7 @@ function installModules() {
done
mkdir -p "${RAMDISK_PATH}/usr/lib/firmware"
KERNEL=$(readConfigKey "kernel" "${USER_CONFIG_FILE}")
local 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
@ -167,10 +153,9 @@ function delToModules() {
function getdepends() {
function _getdepends() {
if [ -f "${TMP_PATH}/modules/${1}.ko" ]; then
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
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
echo "${k}"
_getdepends "${k}"
done
@ -189,7 +174,7 @@ function getdepends() {
unpackModules "${PLATFORM}" "${PKVER}"
_getdepends "${KONAME}" | sort -u
echo "${KONAME}"
local DPS=($(_getdepends "${KONAME}" | tr ' ' '\n' | sort -u))
echo "${DPS[@]}"
rm -rf "${TMP_PATH}/modules"
}

View File

@ -1,10 +1,4 @@
#!/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)"
@ -28,7 +22,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="$(find /sys/class/net/ -mindepth 1 -maxdepth 1 ! -name lo -exec basename {} \; | sort)"
ETHX=$(ls /sys/class/net/ 2>/dev/null | grep -v lo) || true
# 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!")"
@ -89,9 +83,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}"
@ -173,7 +167,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
@ -191,15 +185,15 @@ done
printf "$(TEXT "Waiting IP.\n")"
for N in ${ETHX}; do
COUNT=0
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)"
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)
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
@ -252,7 +246,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,12 +1,4 @@
#!/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)"
@ -156,7 +148,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 ] || [ "$(lspci -d ::107 2>/dev/null | wc -l)" -gt 0 ] && hasHBA=1 || hasHBA=0
[ "$(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
while read -r M A; do
COMPATIBLE=1
if [ ${RESTRICT} -eq 1 ]; then
@ -353,9 +345,8 @@ function productversMenu() {
DIALOG --title "$(TEXT "Product Version")" \
--infobox "$(TEXT "Reconfiguring Synoinfo, Addons and Modules ...")" 0 0
fi
local BASEPATURL BASEPATSUM
BASEPATURL="$(readConfigKey "paturl" "${USER_CONFIG_FILE}")"
BASEPATSUM="$(readConfigKey "patsum" "${USER_CONFIG_FILE}")"
local BASEPATURL="$(readConfigKey "paturl" "${USER_CONFIG_FILE}")"
local BASEPATSUM="$(readConfigKey "patsum" "${USER_CONFIG_FILE}")"
PRODUCTVER=${selver}
writeConfigKey "productver" "${PRODUCTVER}" "${USER_CONFIG_FILE}"
@ -391,7 +382,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
@ -399,7 +390,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}"
@ -490,7 +481,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
@ -498,7 +489,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}"
@ -611,7 +602,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")\""
@ -631,7 +622,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
@ -674,7 +665,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
@ -689,7 +680,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
;;
@ -702,26 +693,28 @@ function addonMenu() {
fi
DIALOG --title "$(TEXT "Addons")" \
--msgbox "$(TEXT "Please upload the *.addon file.")" 0 0
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)"
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
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=$?
if [ ${RET} -ne 0 ]; then
rm -rf "${TMP_UP_PATH}"
return
fi
[ ${RET} -ne 0 ] && return
fi
ADDON="$(untarAddon "${USER_FILE}")"
rm -rf "${TMP_UP_PATH}"
ADDON="$(untarAddon "${TMP_UP_PATH}/${USER_FILE}")"
if [ -n "${ADDON}" ]; then
[ -f "${ADDONS_PATH}/VERSION" ] && rm -f "${ADDONS_PATH}/VERSION"
DIALOG --title "$(TEXT "Addons")" \
@ -770,7 +763,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"
@ -815,11 +808,14 @@ function moduleMenu() {
l)
DIALOG --title "$(TEXT "Modules")" \
--infobox "$(TEXT "Selecting loaded modules")" 0 0
writeConfigKey "modules" "{}" "${USER_CONFIG_FILE}"
KOLIST=""
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}")"
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}"
done
touch ${PART1_PATH}/.build
;;
@ -842,42 +838,47 @@ function moduleMenu() {
[ $? -ne 0 ] && continue
DIALOG --title "$(TEXT "Modules")" \
--msgbox "$(TEXT "Please upload the *.ko file.")" 0 0
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)"
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
if [ -n "${USER_FILE}" ] && [ "${USER_FILE##*.}" = "ko" ]; then
addToModules "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}" "${USER_FILE}"
addToModules ${PLATFORM} "${KPRE:+${KPRE}-}${KVER}" "${TMP_UP_PATH}/${USER_FILE}"
[ -f "${MODULES_PATH}/VERSION" ] && rm -f "${MODULES_PATH}/VERSION"
DIALOG --title "$(TEXT "Modules")" \
--msgbox "$(printf "$(TEXT "Module '%s' added to %s-%s")" "$(basename "${USER_FILE}" .ko)" "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}")" 0 0
rm -rf "${TMP_UP_PATH}"
--msgbox "$(printf "$(TEXT "Module '%s' added to %s-%s")" "${USER_FILE}" "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}")" 0 0
rm -f "${TMP_UP_PATH}/${USER_FILE}"
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)"
DEPS="$(getdepends "${PLATFORM}" "${KPRE:+${KPRE}-}${KVER}" i915) 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.")\n" "${DELS[@]}")" 0 0
--msgbox "$(printf "$(TEXT "Module %s deselected.")" "${DELS[@]}")" 0 0
fi
touch ${PART1_PATH}/.build
;;
@ -1019,7 +1020,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
@ -1036,7 +1037,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
;;
@ -1180,14 +1181,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")" \
@ -1197,7 +1198,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
@ -1214,7 +1215,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
@ -1357,7 +1358,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
@ -1535,14 +1536,20 @@ 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}"
(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=$?
if [ -z "${USER_FILE}" ] || [ ${RET} -ne 0 ]; then
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}"
RET=$?
break
done
popd
if [ ${RET} -ne 0 ] || [ -z "${USER_FILE}" ]; 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
@ -1552,8 +1559,7 @@ function customDTS() {
DIALOG --title "$(TEXT "Custom DTS")" \
--msgbox "$(TEXT "A valid dts file, Automatically import at compile time.")" 0 0
fi
rm -f "${DTC_ERRLOG}"
rm -rf "${TMP_UP_PATH}"
rm -rf "${DTC_ERRLOG}"
touch ${PART1_PATH}/.build
;;
d)
@ -1565,7 +1571,7 @@ function customDTS() {
if [ -f "${USER_UP_PATH}/${MODEL}.dts" ]; then
cp -f "${USER_UP_PATH}/${MODEL}.dts" "${TMP_PATH}/model.dts"
else
ODTB="$(find "${PART2_PATH}" -type f -name "*.dtb" | head -1)"
ODTB="$(ls ${PART2_PATH}/*.dtb 2>/dev/null | head -1)"
if [ -f "${ODTB}" ]; then
dtc -q -I dtb -O dts "${ODTB}" >"${TMP_PATH}/model.dts"
else
@ -1605,7 +1611,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: "
@ -1624,7 +1630,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)
@ -1633,7 +1639,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)
@ -1642,7 +1648,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)
@ -1650,7 +1656,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)
@ -1658,7 +1664,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)
@ -1667,7 +1673,7 @@ function showDisksInfo() {
MSG+="\Zb${NAME}\Zn\nNumber: ${PORTNUM}\n"
NUMPORTS=$((${NUMPORTS} + ${PORTNUM}))
done
[ "$(ls -l /sys/block/mmc* 2>/dev/null | wc -l)" -gt 0 ] && MSG+="\nMMC:\n"
[ $(ls -l /sys/block/mmc* | 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)
@ -1675,7 +1681,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)
@ -1684,7 +1690,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)
@ -1738,7 +1744,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
@ -1753,13 +1759,12 @@ 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 F in /dev/md[0-9]*; do
[ ! -e "${F}" ] && continue
mdadm -S "${F}" >/dev/null 2>&1
for I in $(ls /dev/md[0-9]* 2>/dev/null); do
mdadm -S "${I}" >/dev/null 2>&1
done
fi
for I in ${RESP}; do
@ -1866,7 +1871,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
@ -1896,10 +1901,9 @@ function resetDSMPassword() {
rm -f "${TMP_PATH}/isOk"
(
mkdir -p "${TMP_PATH}/mdX"
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}")"
# 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}")"
for I in ${DSMROOTS}; do
fixDSMRootPart "${I}"
mount -t ext4 "${I}" "${TMP_PATH}/mdX"
@ -1953,7 +1957,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"
@ -1994,7 +1998,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"
@ -2130,7 +2134,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" \
@ -2318,7 +2322,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")" \
@ -2609,9 +2613,9 @@ function savemodrr() {
###############################################################################
# Set static IP
function setStaticIP() {
ETHX="$(find /sys/class/net/ -mindepth 1 -maxdepth 1 ! -name lo -exec basename {} \; | sort)"
ETHX=$(ls /sys/class/net/ 2>/dev/null | grep -v lo) || true
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}"
@ -2735,8 +2739,7 @@ function setWirelessAccount() {
# $1 - KEY
function setProxy() {
local RET=1
local PROXY
PROXY=$(readConfigKey "${1}" "${USER_CONFIG_FILE}")
local 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")" \
@ -2800,11 +2803,10 @@ function changePassword() {
[ $? -ne 0 ] && return
DIALOG --title "$(TEXT "Settings")" \
--infobox "$(TEXT "Setting ...")" 20 100
local STRPASSWD NEWPASSWD
STRPASSWD="$(cat "${TMP_PATH}/resp")"
local 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)"
NEWPASSWD="$(openssl passwd -6 -salt "$(openssl rand -hex 8)" "${STRPASSWD:-rr}")"
local 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
@ -2836,7 +2838,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 ;;
@ -2861,7 +2863,7 @@ function changePassword() {
###############################################################################
# Change ports of TTYD/DUFS/HTTP
function changePorts() {
MSG="$(TEXT "Please fill in a number between 0-65535: (Empty for default value.)")"
local 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}
@ -2931,7 +2933,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 ;;
@ -3359,7 +3361,7 @@ function settingsMenu() {
else
createMicrocode
fi
NEXT="3"
NEXT="e"
;;
4)
changePassword
@ -3416,7 +3418,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
@ -3479,9 +3481,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
@ -3579,7 +3581,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
@ -3604,7 +3606,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
@ -3623,7 +3625,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
@ -3667,13 +3669,12 @@ function updateAddons() {
return 1
fi
for F in ${TMP_PATH}/update/*.addon; do
[ ! -e "${F}" ] && continue
ADDON=$(basename "${F}" .addon)
for PKG in $(ls ${TMP_PATH}/update/*.addon 2>/dev/null); do
ADDON=$(basename ${PKG} .addon)
rm -rf "${TMP_PATH}/update/${ADDON}"
mkdir -p "${TMP_PATH}/update/${ADDON}"
tar -xaf "${F}" -C "${TMP_PATH}/update/${ADDON}" >/dev/null 2>&1
rm -f "${F}"
tar -xaf "${PKG}" -C "${TMP_PATH}/update/${ADDON}" >/dev/null 2>&1
rm -f "${PKG}"
done
SIZENEW="$(du -sm "${TMP_PATH}/update" 2>/dev/null | awk '{print $1}')"
@ -3998,42 +3999,51 @@ 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}"
(cd "${TMP_UP_PATH}" && rz -be) || true
USER_FILE="$(find "${TMP_UP_PATH}" -type f | head -1)"
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
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 "${USER_FILE}" "${SILENT}"
updateRR "${TMP_UP_PATH}/${USER_FILE}" "${SILENT}"
;;
*addons*.zip)
addons*.zip)
rm -f ${TMP_PATH}/addons*.zip
updateAddons "${USER_FILE}" "${SILENT}"
updateAddons "${TMP_UP_PATH}/${USER_FILE}" "${SILENT}"
;;
*modules*.zip)
modules*.zip)
rm -f ${TMP_PATH}/modules*.zip
updateModules "${USER_FILE}" "${SILENT}"
updateModules "${TMP_UP_PATH}/${USER_FILE}" "${SILENT}"
;;
*rp-lkms*.zip)
rp-lkms*.zip)
rm -f ${TMP_PATH}/rp-lkms*.zip
updateLKMs "${USER_FILE}" "${SILENT}"
updateLKMs "${TMP_UP_PATH}/${USER_FILE}" "${SILENT}"
;;
*rr-cks*.zip)
rr-cks*.zip)
rm -f ${TMP_PATH}/rr-cks*.zip
updateCKs "{USER_FILE}" "${SILENT}"
updateCKs "${TMP_UP_PATH}/${USER_FILE}" "${SILENT}"
;;
*)
DIALOG --title "$(TEXT "Update")" \
--msgbox "$(TEXT "Not a valid file, please try again!")" 0 0
;;
esac
rm -rf "${TMP_UP_PATH}"
rm -f "${TMP_UP_PATH}/${USER_FILE}"
fi
;;
b)
@ -4113,7 +4123,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,11 +1,9 @@
#!/usr/bin/env sh
#!/usr/bin/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,12 +1,4 @@
#!/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)"
@ -61,7 +53,7 @@ mkdir -p "${RAMDISK_PATH}"
. "${RAMDISK_PATH}/etc/VERSION"
if [ -n "${PRODUCTVER}" ] && [ -n "${BUILDNUM}" ] && [ -n "${SMALLNUM}" ] &&
([ ! "${PRODUCTVER}" = "${majorversion:-0}.${minorversion:-0}" ] || [ ! "${BUILDNUM}" = "${buildnumber:-0}" ] || [ ! "${SMALLNUM}" = "${smallfixnumber:-0}" ]); then
([ ! "${PRODUCTVER}" = "${majorversion}.${minorversion}" ] || [ ! "${BUILDNUM}" = "${buildnumber}" ] || [ ! "${SMALLNUM}" = "${smallfixnumber}" ]); 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"
@ -110,8 +102,7 @@ for PE in "${PATCHS[@]}"; do
RET=1
echo "Patching with ${PE}" >"${LOG_FILE}"
# ${PE} contains *, so double quotes cannot be added
for PF in ${WORK_PATH}/patch/${PE}; do
[ ! -e "${PF}" ] && continue
for PF in $(ls ${WORK_PATH}/patch/${PE} 2>/dev/null); do
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
@ -157,7 +148,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
@ -205,7 +196,7 @@ echo "inetd" >>"${RAMDISK_PATH}/addons/addons.sh"
echo -n "."
echo "Modify files" >"${LOG_FILE}"
# Remove function from scripts
[ "2" = "${BUILDNUM:0:1}" ] && find "${RAMDISK_PATH}/addons/" -type f -name "*.sh" -exec sed -i 's/function //g' {} \;
[ "2" = "${BUILDNUM:0:1}" ] && sed -i 's/function //g' $(find "${RAMDISK_PATH}/addons/" -type f -name "*.sh")
# Build modules dependencies
# ${WORK_PATH}/depmod -a -b ${RAMDISK_PATH} 2>/dev/null # addon eudev will do this
@ -254,10 +245,8 @@ fi
# Call user patch scripts
echo -n "."
for F in ${SCRIPTS_PATH}/*.sh; do
[ ! -e "${F}" ] && continue
for F in $(ls -1 "${SCRIPTS_PATH}/"*.sh 2>/dev/null); do
echo "Calling ${F}" >"${LOG_FILE}"
# shellcheck source=/dev/null
. "${F}" >>"${LOG_FILE}" 2>&1 || exit 1
done

View File

@ -1,10 +1,4 @@
#!/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)"
@ -18,7 +12,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))
@ -44,23 +38,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,10 +1,4 @@
#!/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 dosfstools cpio xz-utils lz4 lzma bzip2 gzip zstd
sudo apt install -y python-is-python3 python3-pip libelf-dev qemu-utils 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,11 +52,6 @@ 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}"
@ -112,11 +107,11 @@ function init() {
exit 1
fi
. "$(dirname "${BASH_SOURCE[0]}")/rr.env"
pushd "${CHROOT_PATH}/initrd/opt/rr" || exit 1
pushd "${CHROOT_PATH}/initrd/opt/rr" >/dev/null
echo "init"
./init.sh
local RET=$?
popd || exit 1
popd >/dev/null
[ ${RET} -ne 0 ] && echo "Failed." || echo "Success."
exit ${RET}
}
@ -128,7 +123,7 @@ function config() {
fi
. "$(dirname "${BASH_SOURCE[0]}")/rr.env"
local RET=1
pushd "${CHROOT_PATH}/initrd/opt/rr" || exit 1
pushd "${CHROOT_PATH}/initrd/opt/rr" >/dev/null
while true; do
if [ -z "${1}" ]; then
echo "menu"
@ -143,7 +138,7 @@ function config() {
fi
break
done
popd || exit 1
popd >/dev/null
[ ${RET} -ne 0 ] && echo "Failed." || echo "Success."
exit ${RET}
}
@ -155,7 +150,7 @@ function build() {
fi
. "$(dirname "${BASH_SOURCE[0]}")/rr.env"
local RET=1
pushd "${CHROOT_PATH}/initrd/opt/rr" || exit 1
pushd "${CHROOT_PATH}/initrd/opt/rr" >/dev/null
while true; do
echo "build"
./menu.sh make -1 || break
@ -164,7 +159,7 @@ function build() {
RET=0
break
done
popd || exit 1
popd >/dev/null
[ ${RET} -ne 0 ] && echo "Failed." || echo "Success."
exit ${RET}
}
@ -186,11 +181,6 @@ 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}"
@ -220,4 +210,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,8 +37,7 @@ 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
STATUS=$(curl -#L -w "%{http_code}" "${PAT_URL}" -o "${CACHE_DIR}/${PAT_FILE}")
local 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}"
@ -85,12 +84,11 @@ 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}"
@ -119,12 +117,11 @@ 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}"
@ -150,12 +147,11 @@ 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}"
@ -181,12 +177,11 @@ 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}"
@ -196,15 +191,11 @@ 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 F in ${CACHE_DIR}/*.addon; do
[ ! -e "${F}" ] && continue
ADDON=$(basename "${F}" .addon)
# shellcheck disable=SC2115
rm -rf "${DEST_PATH}/${ADDON}"
for PKG in "${CACHE_DIR}"/*.addon; do
ADDON=$(basename "${PKG}" .addon)
mkdir -p "${DEST_PATH}/${ADDON}"
echo "Extracting ${F} to ${DEST_PATH}/${ADDON}"
tar -xaf "${F}" -C "${DEST_PATH}/${ADDON}"
rm -f "${F}"
echo "Extracting ${PKG} to ${DEST_PATH}/${ADDON}"
tar -xaf "${PKG}" -C "${DEST_PATH}/${ADDON}"
done
rm -rf "${CACHE_DIR}"
rm -f "${CACHE_FILE}"
@ -227,12 +218,11 @@ 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}"
@ -260,8 +250,7 @@ function repackInitrd() {
local RDXZ_PATH="rdxz_tmp"
mkdir -p "${RDXZ_PATH}"
local INITRD_FORMAT
INITRD_FORMAT=$(file -b --mime-type "${INITRD_FILE}")
local 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 ;;
@ -276,7 +265,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 ;;
@ -314,20 +303,19 @@ 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
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=$(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() {
local BLIMAGE=${1}
local VMNAME=${2}
BLIMAGE=${1}
VMNAME=${2}
if ! command -v qemu-img &>/dev/null; then
sudo apt install -y qemu-utils
@ -409,10 +397,10 @@ _EOF_
function convertvmx() {
local BLIMAGE=${1}
local VMXPATH=${2}
local VMNAME
BLIMAGE="$(realpath "${BLIMAGE}")"
VMXPATH="$(realpath "${VMXPATH}")"
VMNAME="$(basename "${VMXPATH}" .vmx)"
local VMNAME="$(basename "${VMXPATH}" .vmx)"
createvmx "${BLIMAGE}" "${VMNAME}"
@ -426,11 +414,10 @@ function convertvmx() {
function convertova() {
local BLIMAGE=${1}
local OVAPATH=${2}
local VMNAME
BLIMAGE="$(realpath "${BLIMAGE}")"
OVAPATH="$(realpath "${OVAPATH}")"
VMNAME="$(basename "${OVAPATH}" .ova)"
local VMNAME="$(basename "${OVAPATH}" .ova)"
createvmx "${BLIMAGE}" "${VMNAME}"

View File

@ -6,17 +6,17 @@
# See /LICENSE for more information.
#
# 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 dosfstools cpio xz-utils lz4 lzma bzip2 gzip zstd
# 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 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 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
#
# export TOKEN="${1}"
@ -42,12 +42,10 @@ 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="${CHROOT_PATH}"
export CHROOT_PATH="$(realpath files)"
(
cd "${CHROOT_PATH}/initrd/opt/rr" || exit 1
cd "${CHROOT_PATH}/initrd/opt/rr"
./init.sh
./menu.sh modelMenu "${1}"
./menu.sh productversMenu "${2:-7.2}"
@ -63,14 +61,9 @@ 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
rm -rf "/tmp/mnt/p${i}"
mkdir -p "/tmp/mnt/p${i}"
@ -110,8 +103,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