Skip to content

Instantly share code, notes, and snippets.

@theofficialgman
Last active March 24, 2023 18:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save theofficialgman/5f20f451dcc587d2a51d934f693267f5 to your computer and use it in GitHub Desktop.
Save theofficialgman/5f20f451dcc587d2a51d934f693267f5 to your computer and use it in GitHub Desktop.
Nintendo Switch Linux reboot to payload YAD GUI
#!/bin/bash
error() { #red text and exit 1
echo -e "\e[91m$1\e[0m" 1>&2
yad --class Reboot-To-Payload --name "Reboot To Payload" --no-escape --fixed --show-uri --center --image "dialog-error" --borders="20" --title "ERROR" \
--text="$1" --wrap \
--window-icon=/usr/share/nvpmodel_indicator/nv_logo.svg \
--button="Exit":0
exit 1
}
if [[ $(id -u) != 0 ]]; then
error "This script is designed to be run as root/sudo."
fi
SWR_VER=$(cat /etc/switchroot_version.conf)
# version function
version() {
echo "$@" | awk -F. '{ printf("%d%03d%03d\n", $1,$2,$3); }'
}
if [ $(version $SWR_VER) -lt $(version "5.0.0") ]; then
error "L4T 5.0.0+ with hekate 6.0.0+ is required to use this script. Exiting without execution..."
fi
status() { #cyan text to indicate what is happening
echo -e "\e[96m$1\e[0m"
}
status_green() { #announce the success of a major action
echo -e "\e[92m$1\e[0m"
}
cleanup() {
[ -z "$BOOTSTACK" ] && error "cleanup(): BOOTSTACK variable not set"
[ -z "$temp_folder" ] && error "cleanup(): temp_folder variable not set"
status "Unmounting boot disk" >&2
umount /${BOOTSTACK}/boot_disk || true
rm -rf $temp_folder
status_green "temporary folder removed"
}
gui() {
unset INDEX
unset retrun_code
[ -z "$uniq_selection" ] && error "gui(): uniq_selection array not set"
[ -z "$button1" ] && button1="Back"
[ -z "$button2" ] && button2="Reboot"
INDEX=$(
yad --class Reboot-To-Payload --name "Reboot To Payload" --center \
--width="450" \
--height="450" \
--title "R2P Helper" \
--text "Please choose a category or reboot options." \
--borders="20" \
--window-icon=/usr/share/nvpmodel_indicator/nv_logo.svg \
--list \
--separator='' \
--column=:IMG \
--column "Payload Name" \
--column "hekate Index" \
--column=@font@ \
--hide-column=3 \
--print-column=3 \
"${uniq_selection[@]}" \
--button="$button1":1 \
--button="$button2":0
)
return_code="$?"
unset button1
unset button2
}
section_parser() {
[ -z "$ini_file" ] && error "section_parser(): ini_file variable not set"
[ -z "$BOOTSTACK" ] && error "section_parser(): BOOTSTACK variable not set"
[ -z "$temp_folder" ] && error "section_parser(): temp_folder variable not set"
readarray -t sections < <(cat "$ini_file" | sed 's/\r$//' | grep '^\[.*\]')
# loop through sections in .ini
for section in "${sections[@]}"; do
echo "$section"
# skip [config] for launch payloads to match hekate
if [[ "$INDEX" == "0" ]] && [[ "$section" == '[config]' ]]; then
continue
fi
section_name="${section//[}"
section_name="${section_name//]}"
ids+=("$section_name")
section="${section//[/\\[}"
section="${section//]/\\]}"
icon_path="$(cat "$ini_file" | sed 's/\r$//' | sed -n "/^$section/,/^\[.*\]/"'{ /^\[.*\]/!p }' | sed -n 's/^icon=//p' )"
ids_icon+=($icon_path)
mkdir -p "$(dirname "$icon_path")"
# only generate png if bmp file is found and png is not already generated
if [ -f "/${BOOTSTACK}/boot_disk/$icon_path" ] && [ ! -f "$temp_folder/${icon_path//.bmp/.png}" ]; then
convert "/${BOOTSTACK}/boot_disk/$icon_path" -resize 48 "$temp_folder/${icon_path//.bmp/.png}"
fi
done
}
BOOTSTACK="opt/switchroot"
SWR_DIR=$(sed -ne 's/.*swr_dir=//;T' -e 's/\s.*$//p' /proc/cmdline)
MMC_BLK=$(sed -ne 's/.*boot_m=//;T' -e 's/\s.*$//p' /proc/cmdline)
MMC_PART=$(sed -ne 's/.*boot_p=//;T' -e 's/\s.*$//p' /proc/cmdline)
DEV_MMC="mmcblk0"
font="20"
if [[ ! -n ${SWR_DIR} ]]; then SWR_DIR="switchroot/ubuntu"; fi
if [[ ! -n ${MMC_BLK} ]]; then MMC_BLK=0; fi
if [[ ! -n ${MMC_PART} ]]; then MMC_PART=1; fi
if [[ -e /dev/mmcblk1 ]] && [[ ${MMC_BLK} -eq 1 ]]; then DEV_MMC="mmcblk1"; fi
mkdir -p /${BOOTSTACK}/boot_disk || true
#set -e
echo "Mounting boot disk ${DEV_MMC}p${MMC_PART}" >&2
mount /dev/${DEV_MMC}p${MMC_PART} /${BOOTSTACK}/boot_disk || mountpoint -q /${BOOTSTACK}/boot_disk
# make temporary folder for storing all bmp -> png converted files
temp_folder=$(mktemp -d)
cd $temp_folder
# create default icons
for icon_path in bootloader/res/icon_payload.bmp bootloader/res/icon_switch.bmp ; do
mkdir -p "$(dirname "$icon_path")"
if [ -f "/${BOOTSTACK}/boot_disk/$icon_path" ]; then
convert "/${BOOTSTACK}/boot_disk/$icon_path" -resize 48 "$temp_folder/${icon_path//.bmp/.png}"
fi
done
while true; do
# show YAD GUI for selecting category
uniq_selection=()
uniq_selection+=("$temp_folder/bootloader/res/icon_payload.png" "Launch" "0" "$font")
uniq_selection+=("$temp_folder/bootloader/res/icon_payload.png" "More Configs" "1" "$font")
uniq_selection+=(drive-removable-media "UMS" "2" "$font")
uniq_selection+=(applications-utilities "hekate menu" "3" "$font")
uniq_selection+=(system-reboot "Normal Reboot" "4" "$font")
button1="Exit"
button2="Select"
gui
if [ "$INDEX" == "2" ]; then
# UMS
status_green "UMS Section"
uniq_selection=()
uniq_selection+=(media-flash "SD Card" "0" "$font")
uniq_selection+=(drive-harddisk "eMMC BOOT0" "1" "$font")
uniq_selection+=(drive-harddisk "eMMC BOOT1" "2" "$font")
uniq_selection+=(drive-harddisk "eMMC GPP" "3" "$font")
uniq_selection+=(media-flash "emuMMC BOOT0" "4" "$font")
uniq_selection+=(media-flash "emuMMC BOOT1" "5" "$font")
uniq_selection+=(media-flash "emuMMC GPP" "6" "$font")
gui
if [ ! -z "$INDEX" ]; then
cleanup
echo "ums" > /sys/devices/r2p/action
echo $INDEX > /sys/devices/r2p/param1
reboot
break
fi
elif [ "$INDEX" == "3" ]; then
# hekate
cleanup
echo "bootloader" > /sys/devices/r2p/action
reboot
break
elif [ "$INDEX" == "4" ]; then
# Normal reboot
cleanup
echo "normal" > /sys/devices/r2p/action
reboot
break
elif [ "$INDEX" == "0" ]; then
# Launch payloads
# payloads section
status_green "Payloads Section"
# list ini files by name
# more configs section
ini_file="/${BOOTSTACK}/boot_disk/bootloader/hekate_ipl.ini"
ids=()
ids_icon=()
section_parser
uniq_selection=()
END="${#ids[@]}"
for ((i=0;i<END;i++)); do
if [ -f "$temp_folder/${ids_icon[i]//.bmp/.png}" ]; then
uniq_selection+=("$temp_folder/${ids_icon[i]//.bmp/.png}" "${ids[i]}" "$((i+1))" "$font")
else
uniq_selection+=(image-missing "${ids[i]}" "$((i+1))" "$font")
fi
done
gui
if [ ! -z "$INDEX" ]; then
cleanup
echo self > /sys/devices/r2p/action
echo $INDEX > /sys/devices/r2p/param1
echo 0 > /sys/devices/r2p/param2
reboot
break
fi
elif [ "$INDEX" == "1" ]; then
# list ini files by name
# more configs section
status_green "More Configs Section"
ini_files=($( LC_ALL=C ls /${BOOTSTACK}/boot_disk/bootloader/ini/*.ini))
ids=()
ids_icon=()
# loop through .ini files
for ini_file in "${ini_files[@]}"; do
section_parser
done
# show YAD GUI for selecting reboot command
uniq_selection=()
END="${#ids[@]}"
for ((i=0;i<END;i++)); do
if [ -f "$temp_folder/${ids_icon[i]//.bmp/.png}" ]; then
uniq_selection+=("$temp_folder/${ids_icon[i]//.bmp/.png}" "${ids[i]}" "$((i+1))" "$font")
else
uniq_selection+=(image-missing "${ids[i]}" "$((i+1))" "$font")
fi
done
gui
if [ ! -z "$INDEX" ]; then
cleanup
echo self > /sys/devices/r2p/action
echo $INDEX > /sys/devices/r2p/param1
echo 1 > /sys/devices/r2p/param2
reboot
break
fi
else
break
fi
done
cleanup
exit 0
@theofficialgman
Copy link
Author

theofficialgman commented Jan 1, 2023

# install dependencies
sudo apt install yad imagemagick -y
# install program and add a .desktop file for it that can be run from the apps list
sudo mkdir -p /usr/local/bin
sudo mkdir -p /usr/local/share/applications
sudo wget https://gist.github.com/theofficialgman/5f20f451dcc587d2a51d934f693267f5/raw/f0dc9325b7516573de4aabef86f38bcaa5eb6f49/reboot-to-payload.sh -O /usr/local/bin/reboot-to-payload.sh
sudo chmod +x /usr/local/bin/reboot-to-payload.sh
sudo sh -c "cat > /etc/sudoers.d/reboot_sudo << _EOF_
"$USER" ALL = NOPASSWD: "/usr/local/bin/reboot-to-payload.sh"
_EOF_"
echo "[Desktop Entry]
Type=Application
Exec=sudo /usr/local/bin/reboot-to-payload.sh
Name=Reboot to Payload (R2P)
Icon=/usr/share/nvpmodel_indicator/nv_logo.svg
StartupWMClass=Reboot-To-Payload
Categories=System" | sudo tee /usr/local/share/applications/reboot-to-payload.desktop

@tuxfamily
Copy link

Thank you, very useful!
However, the shortcut does not work for me.
It seems that the sudo rule is not applied (even after reboot).
A quick workaround to avoid "sudo" is:
chmod u+s /usr/local/bin/reboot-to-payload.sh
and removing the lines 13>15 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment