PSBBN-Definitive-English-Patch/02-PSBBN-Installer.sh
2025-01-05 22:45:56 +00:00

501 lines
19 KiB
Bash
Executable File

#!/bin/bash
# Set terminal size: 100 columns and 40 rows
echo -e "\e[8;40;100t"
# Set paths
TOOLKIT_PATH="$(pwd)"
ASSETS_DIR="${TOOLKIT_PATH}/assets"
INSTALL_LOG="${TOOLKIT_PATH}/PSBBN-installer.log"
clear
cd "${TOOLKIT_PATH}"
# Check if the helper files exists
if [[ ! -f "${TOOLKIT_PATH}/helper/PFS Shell.elf" || ! -f "${TOOLKIT_PATH}/helper/HDL Dump.elf" ]]; then
echo "Required helper files not found. Please make sure you are in the 'PSBBN-Definitive-English-Patch'"
echo "directory and try again."
exit 1
fi
echo "####################################################################">> "${INSTALL_LOG}";
date >> "${INSTALL_LOG}"
echo >> "${INSTALL_LOG}"
echo "Path set to: $TOOLKIT_PATH" >> "${INSTALL_LOG}"
echo "Helper files found." >> "${INSTALL_LOG}"
# Fetch updates from the remote
git fetch >> "${INSTALL_LOG}" 2>&1
# Check the current status of the repository
LOCAL=$(git rev-parse @)
REMOTE=$(git rev-parse @{u})
BASE=$(git merge-base @ @{u})
if [ "$LOCAL" = "$REMOTE" ]; then
echo "The repository is up to date." >> "${INSTALL_LOG}"
else
echo "Downloading update..."
git reset --hard && git pull --force >> "${INSTALL_LOG}" 2>&1
echo
echo "The script has been updated to the latest version." | tee -a "${INSTALL_LOG}"
read -p "Press any key to exit, then run the script again."
exit 0
fi
# Choose the PS2 storage device
while true; do
clear
echo " ______ _________________ _ _ _____ _ _ _ ";
echo " | ___ \/ ___| ___ \ ___ \ \ | | |_ _| | | | | | ";
echo " | |_/ /\ \`--.| |_/ / |_/ / \| | | | _ __ ___| |_ __ _| | | ___ _ __ ";
echo " | __/ \`--. \ ___ \ ___ \ . \` | | || '_ \/ __| __/ _\` | | |/ _ \ '__|";
echo " | | /\__/ / |_/ / |_/ / |\ | _| || | | \__ \ || (_| | | | __/ | ";
echo " \_| \____/\____/\____/\_| \_/ \___/_| |_|___/\__\__,_|_|_|\___|_| ";
echo " ";
echo " Written by CosmicScale"
echo
echo | tee -a "${INSTALL_LOG}"
lsblk -p -o MODEL,NAME,SIZE,LABEL,MOUNTPOINT | tee -a "${INSTALL_LOG}"
echo | tee -a "${INSTALL_LOG}"
read -p "Choose your PS2 HDD from the list above (e.g., /dev/sdx): " DEVICE
# Validate input
if [[ $DEVICE =~ ^/dev/sd[a-z]$ ]]; then
# Check the size of the chosen device
SIZE_CHECK=$(lsblk -o NAME,SIZE -b | grep -w $(basename $DEVICE) | awk '{print $2}')
# Convert size to GB (1 GB = 1,000,000,000 bytes)
size_gb=$(echo "$SIZE_CHECK / 1000000000" | bc)
if (( size_gb < 200 )); then
echo
echo "Error: Device is $size_gb GB. Required minimum is 200 GB."
read -p "Press any key to exit."
exit 1
fi
echo
echo -e "Are you sure you want to write to ${DEVICE}?" | tee -a "${INSTALL_LOG}"
read -p "This will erase all data on the drive. (yes/no): " CONFIRM
if [[ $CONFIRM == "yes" ]]; then
break
else
echo "Aborted." | tee -a "${INSTALL_LOG}"
read -p "Press any key to exit..."
exit 1
fi
else
echo
echo "Error: Invalid input. Please enter a valid device name (e.g., /dev/sdx)."
read -p "Press any key to try again..."
continue
fi
done
# Find all mounted volumes associated with the device
mounted_volumes=$(lsblk -ln -o MOUNTPOINT "$DEVICE" | grep -v "^$")
# Iterate through each mounted volume and unmount it
echo | tee -a "${INSTALL_LOG}"
echo "Unmounting volumes associated with $DEVICE..."
for mount_point in $mounted_volumes; do
echo "Unmounting $mount_point..." | tee -a "${INSTALL_LOG}"
if sudo umount "$mount_point"; then
echo "Successfully unmounted $mount_point." | tee -a "${INSTALL_LOG}"
else
echo "Failed to unmount $mount_point. Please unmount manually." | tee -a "${INSTALL_LOG}"
read -p "Press any key to exit..."
exit 1
fi
done
echo "All volumes unmounted for $DEVICE."
# URL of the webpage
URL="https://archive.org/download/psbbn-definitive-english-patch-v2"
echo | tee -a "${INSTALL_LOG}"
echo "Checking for latest version of the PSBBN Definitive English patch..." | tee -a "${INSTALL_LOG}"
# Download the HTML of the page
HTML_FILE=$(mktemp)
wget -O "$HTML_FILE" "$URL" >> "${INSTALL_LOG}" 2>&1
# Extract .gz filenames from the HTML
COMBINED_LIST=$(grep -oP 'psbbn-definitive-image-v[0-9]+\.[0-9]+\.gz' "$HTML_FILE")
# Extract version numbers and sort them
VERSION_LIST=$(echo "$COMBINED_LIST" | \
grep -oP 'v[0-9]+\.[0-9]+' | \
sed 's/v//' | \
sort -V)
# Determine the latest version from the sorted list
LATEST_VERSION=$(echo "$VERSION_LIST" | tail -n 1)
if [ -z "$LATEST_VERSION" ]; then
echo "Could not find the latest version." | tee -a "${INSTALL_LOG}"
# If $LATEST_VERSION is empty, check for psbbn-definitive-image*.gz files
IMAGE_FILE=$(ls "${ASSETS_DIR}"/psbbn-definitive-image*.gz 2>/dev/null)
if [ -n "$IMAGE_FILE" ]; then
# If image file exists, set LATEST_FILE to the image file name
LATEST_FILE=$(basename "$IMAGE_FILE")
echo "Found local file: ${LATEST_FILE}" | tee -a "${INSTALL_LOG}"
else
rm "$HTML_FILE"
echo "Failed to download PSBBN image file. Aborting." | tee -a "${INSTALL_LOG}"
read -p "Press any key to exit..."
exit 1
fi
else
LATEST_FILE="psbbn-definitive-image-v${LATEST_VERSION}.gz"
echo "Latest version of PSBBN Definitive English patch is v${LATEST_VERSION}" | tee -a "${INSTALL_LOG}"
fi
# Check for and delete older files
for file in "${ASSETS_DIR}"/psbbn-definitive-image*.gz; do
if [[ -f "$file" && "$(basename "$file")" != "$LATEST_FILE" ]]; then
echo "Deleting old file: $file" | tee -a "${INSTALL_LOG}"
rm "$file"
fi
done
# Check if the latest file exists in ${ASSETS_DIR}
if [[ -f "${ASSETS_DIR}/${LATEST_FILE}" && ! -f "${ASSETS_DIR}/${LATEST_FILE}.st" ]]; then
echo "File ${LATEST_FILE} exists in ${ASSETS_DIR}." | tee -a "${INSTALL_LOG}"
echo "Skipping download" | tee -a "${INSTALL_LOG}"
else
# Construct the full URL for the .gz file and download it
ZIP_URL="$URL/$LATEST_FILE"
echo "Downloading ${LATEST_FILE}..." | tee -a "${INSTALL_LOG}"
axel -n 8 -a "$ZIP_URL" -o "${ASSETS_DIR}"
# Check if the file was downloaded successfully
if [[ -f "${ASSETS_DIR}/${LATEST_FILE}" && ! -f "${ASSETS_DIR}/${LATEST_FILE}.st" ]]; then
echo "Download completed: ${LATEST_FILE}" | tee -a "${INSTALL_LOG}"
else
echo "Download failed for ${LATEST_FILE}. Please check your internet connection and try again." | tee -a "${INSTALL_LOG}"
read -p "Press any key to exit..."
exit 1
fi
fi
# Clean up
rm "$HTML_FILE"
echo | tee -a "${INSTALL_LOG}"
echo "Checking for POPS binaries..."
# Check POPS files exist
if [[ -f "${ASSETS_DIR}/POPS-binaries-main/POPS.ELF" && -f "${ASSETS_DIR}/POPS-binaries-main/IOPRP252.IMG" ]]; then
echo "Both POPS.ELF and IOPRP252.IMG exist in ${ASSETS_DIR}." | tee -a "${INSTALL_LOG}"
echo "Skipping download" | tee -a "${INSTALL_LOG}"
else
echo "One or both files are missing in ${ASSETS_DIR}." | tee -a "${INSTALL_LOG}"
# Check if POPS-binaries-main.zip exists
if [[ -f "${ASSETS_DIR}/POPS-binaries-main.zip" && ! -f "${ASSETS_DIR}/POPS-binaries-main.zip.st" ]]; then
echo | tee -a "${INSTALL_LOG}"
echo "POPS-binaries-main.zip found in ${ASSETS_DIR}. Extracting..." | tee -a "${INSTALL_LOG}"
unzip -o "${ASSETS_DIR}/POPS-binaries-main.zip" -d "${ASSETS_DIR}" >> "${INSTALL_LOG}" 2>&1
else
echo | tee -a "${INSTALL_LOG}"
echo "Downloading POPS binaries..." | tee -a "${INSTALL_LOG}"
axel -a https://archive.org/download/pops-binaries-PS2/POPS-binaries-main.zip -o "${ASSETS_DIR}"
unzip -o "${ASSETS_DIR}/POPS-binaries-main.zip" -d "${ASSETS_DIR}" >> "${INSTALL_LOG}" 2>&1
fi
# Check if both POPS.ELF and IOPRP252.IMG exist after extraction
if [[ -f "${ASSETS_DIR}/POPS-binaries-main/POPS.ELF" && -f "${ASSETS_DIR}/POPS-binaries-main/IOPRP252.IMG" ]]; then
echo | tee -a "${INSTALL_LOG}"
echo "POPS binaries successfully extracted." | tee -a "${INSTALL_LOG}"
else
echo | tee -a "${INSTALL_LOG}"
echo "Error: One or both files (POPS.ELF, IOPRP252.IMG) are missing after extraction." | tee -a "${INSTALL_LOG}"
read -p "You can install POPS manually later. Press any key to continue..." | tee -a "${INSTALL_LOG}"
fi
fi
PSBBN_IMAGE="${ASSETS_DIR}/${LATEST_FILE}"
# Write the PSBBN image
echo | tee -a "${INSTALL_LOG}"
echo "Writing the PSBBN image to ${DEVICE}..." | tee -a "${INSTALL_LOG}"
if gunzip -c ${PSBBN_IMAGE} | sudo dd of=${DEVICE} bs=4M status=progress 2>&1 | tee -a "${INSTALL_LOG}" ; then
sync
echo
echo "Verifying installation..."
if sudo "${TOOLKIT_PATH}"/helper/HDL\ Dump.elf toc "${DEVICE}" | grep -q '__common'; then
echo "Verification successful. PSBBN image installed successfully." | tee -a "${INSTALL_LOG}"
read -p "Press any key to continue.."
else
echo "Error: Verification failed on ${DEVICE}." | tee -a "${INSTALL_LOG}"
read -p "Press any key to exit..."
exit 1
fi
else
echo "Error: Failed to write the image to ${DEVICE}." | tee -a "${INSTALL_LOG}"
read -p "Press any key to exit..."
exit 1
fi
# Function to find available space
function function_space() {
output=$(sudo "${TOOLKIT_PATH}"/helper/HDL\ Dump.elf toc ${DEVICE} 2>&1)
# Check for the word "aborting" in the output
if echo "$output" | grep -q "aborting"; then
echo "${DEVICE}: APA partition is broken; aborting." | tee -a "${INSTALL_LOG}"
read -p "Press any key to exit..."
exit 1
fi
# Extract the "used" value, remove "MB" and any commas
used=$(echo "$output" | awk '/used:/ {print $6}' | sed 's/,//; s/MB//')
capacity=124416
# Calculate available space (capacity - used)
available=$((capacity - used))
}
# Call the function retreive avaliable space
function_space
# Prompt user for partition size for music, validate input, and keep asking until valid input is provided
while true; do
echo | tee -a "${INSTALL_LOG}"
echo "What size would you like the \"Music\" partition to be?" | tee -a "${INSTALL_LOG}"
echo "Minimum 10 GB, Maximum 40 GB" | tee -a "${INSTALL_LOG}"
read -p "Enter partition size (in GB): " gb_size
# Check if the input is a valid number
if [[ ! "$gb_size" =~ ^[0-9]+$ ]]; then
echo "Invalid input. Please enter a valid number." | tee -a "${INSTALL_LOG}"
continue
fi
# Check if the value is within the valid range
if (( gb_size >= 10 && gb_size <= 40 )); then
music_partition=$((gb_size * 1024 - 2048))
echo | tee -a "${INSTALL_LOG}"
echo "You have selected $gb_size GB for the \"Music\" partition." | tee -a "${INSTALL_LOG}"
# Ask for confirmation
read -p "Are you sure you want to proceed? (y/n): " confirm
if [[ "$confirm" =~ ^[Yy]$ ]]; then
break # Exit the loop
fi
else
echo "Invalid size. Please enter a value between 10 and 40 GB." | tee -a "${INSTALL_LOG}"
fi
done
# Prompt user for partition size for POPS, validate input, and keep asking until valid input is provided
while true; do
GB=$(((available - 14976 - music_partition ) / 1024))
echo | tee -a "${INSTALL_LOG}"
echo "What size would you like the \"POPS\" partition to be?" | tee -a "${INSTALL_LOG}"
echo "All remaining space will be made available for OPL Launcher partitions" | tee -a "${INSTALL_LOG}"
echo "Minimum 10 GB, Maximum $GB GB" | tee -a "${INSTALL_LOG}"
read -p "Enter partition size (in GB): " gb_size
# Check if the input is a valid number
if [[ ! "$gb_size" =~ ^[0-9]+$ ]]; then
echo "Invalid input. Please enter a valid number." | tee -a "${INSTALL_LOG}"
continue
fi
# Check if the value is within the valid range
if (( gb_size >= 10 && gb_size <= $GB )); then
pops_partition=$((gb_size * 1024))
game_partitions=$(((available - 2048 - music_partition - pops_partition) / 128))
echo | tee -a "${INSTALL_LOG}"
echo "You have selected $gb_size GB for the \"POPS\" partition." | tee -a "${INSTALL_LOG}"
echo "This will leave enough space for $game_partitions games" | tee -a "${INSTALL_LOG}"
# Ask for confirmation
read -p "Are you sure you want to proceed? (y/n): " confirm
if [[ "$confirm" =~ ^[Yy]$ ]]; then
break # Exit the loop
fi
else
echo "Invalid size. Please enter a value between 10 and $GB GB." | tee -a "${INSTALL_LOG}"
fi
done
COMMANDS="device ${DEVICE}\n"
COMMANDS+="mkpart __linux.8 ${music_partition}M REISER\n"
COMMANDS+="mkpart __.POPS ${pops_partition}M PFS\n"
COMMANDS+="mkpart +OPL 128M PFS\nexit"
echo -e "$COMMANDS" | sudo "${TOOLKIT_PATH}/helper/PFS Shell.elf" >> "${INSTALL_LOG}" 2>&1
# Pipe all commands to PFS Shell for mounting, copying, and unmounting
echo -e "$COMMANDS" | sudo "${TOOLKIT_PATH}/helper/PFS Shell.elf" >> "${INSTALL_LOG}" 2>&1
echo | tee -a "${INSTALL_LOG}"
echo "Installing POPS and OPL..." | tee -a "${INSTALL_LOG}"
cd "${TOOLKIT_PATH}/assets/"
# Copy POPS files and OPL to relevent partitions
COMMANDS="device ${DEVICE}\n"
COMMANDS+="mount +OPL\n"
COMMANDS+="put OPNPS2LD.ELF\n"
COMMANDS+="umount\n"
COMMANDS+="mount __common\n"
COMMANDS+="mkdir POPS\n"
COMMANDS+="cd POPS\n"
COMMANDS+="put IGR_BG.TM2\n"
COMMANDS+="put IGR_NO.TM2\n"
COMMANDS+="put IGR_YES.TM2\n"
COMMANDS+="lcd POPS-binaries-main\n"
COMMANDS+="put POPS.ELF\n"
COMMANDS+="put IOPRP252.IMG\n"
COMMANDS+="cd ..\n"
COMMANDS+="umount\n"
COMMANDS+="exit"
# Pipe all commands to PFS Shell for mounting, copying, and unmounting
echo -e "$COMMANDS" | sudo "${TOOLKIT_PATH}/helper/PFS Shell.elf" >> "${INSTALL_LOG}" 2>&1
cd "${TOOLKIT_PATH}"
#//////////////////////////////////////////////// APA-Jail code by Berion ////////////////////////////////////////////////
function function_apajail_magic_number() {
echo ${MAGIC_NUMBER} | xxd -r -p > /tmp/apajail_magic_number.bin
sudo dd if=/tmp/apajail_magic_number.bin of=${DEVICE} bs=8 count=1 seek=28 conv=notrunc >> "${INSTALL_LOG}" 2>&1
}
function function_make_ps2_dirs() {
if [ ! -d "/tmp/ps2_dirs" ]; then
mkdir /tmp/ps2_dirs
fi
if [ "$(echo ${DEVICE} | grep -o /dev/loop)" = "/dev/loop" ]; then
sudo mount ${DEVICE}p${PARTITION_NUMBER} /tmp/ps2_dirs
else sudo mount ${DEVICE}${PARTITION_NUMBER} /tmp/ps2_dirs
fi
cd /tmp/ps2_dirs
sudo mkdir -p APPS/ # Open PS2 Loader: applications
sudo mkdir -p ART/ # Open PS2 Loader: disc covers (<GameID>_COV.png, <GameID>_ICO.png, <GameID>_SCR.png etc.)
sudo mkdir -p CFG/ # Open PS2 Loader: per game configs (<GameID>.cfg)
sudo mkdir -p CHT/ # Open PS2 Loader: cheats (<GameID>.cht)
sudo mkdir -p CD/ # Open PS2 Loader: CD disc images (*.iso, *.zso)
sudo mkdir -p DVD/ # Open PS2 Loader: DVD disc images (*.iso, *.zso)
sudo mkdir -p LNG # Open PS2 Loader: Language files
sudo mkdir -p THM/ # Open PS2 Loader: theme dirs (thm_<ThemeName>/*)
sudo mkdir -p VMC/ # Open PS2 Loader: non-ECC PS2 Memory Card images (generic or <GameID>_0.bin, <GameID>_1.bin)
sync
sudo umount -l /tmp/ps2_dirs
}
function function_apa_checksum_fix() {
sudo dd if=${DEVICE} of=/tmp/apa_header_full.bin bs=512 count=2 >> "${INSTALL_LOG}" 2>&1
"${TOOLKIT_PATH}/helper/PS2 APA Header Checksum Fixer.elf" /tmp/apa_header_full.bin | sed -n 8p | awk '{print $6}' | xxd -r -p > /tmp/apa_header_checksum.bin
sudo dd if=/tmp/apa_header_checksum.bin of=${DEVICE} conv=notrunc >> "${INSTALL_LOG}" 2>&1
}
function function_clear_temp() {
sudo rm /tmp/apa_header_address.bin &> /dev/null
sudo rm /tmp/apa_header_boot.bin &> /dev/null
sudo rm /tmp/apa_header_checksum.bin &> /dev/null
sudo rm /tmp/apa_header_full.bin &> /dev/null
sudo rm /tmp/apa_journal.bin &> /dev/null
sudo rm /tmp/apa_header_probe.bin &> /dev/null
sudo rm /tmp/apa_header_size.bin &> /dev/null
sudo rm /tmp/apajail_magic_number.bin &> /dev/null
sudo rm /tmp/apa_index.xz &> /dev/null
sudo rm /tmp/gpt_2nd.xz &> /dev/null
}
echo | tee -a "${INSTALL_LOG}"
echo "Running APA-Jail by Berion..." | tee -a "${INSTALL_LOG}"
# Signature injection (type A2):
MAGIC_NUMBER="4150414A2D413200"
function_apajail_magic_number
# Setting up MBR:
{
echo -e ",128GiB,17\n,32MiB,17\n,,07" | sudo sfdisk ${DEVICE}
sudo partprobe ${DEVICE}
if [ "$(echo ${DEVICE} | grep -o /dev/loop)" = "/dev/loop" ]; then
sudo mkfs.ext2 -L "RECOVERY" ${DEVICE}p2
sudo mkfs.exfat -c 32K -L "OPL" ${DEVICE}p3
else
sleep 4
sudo mkfs.ext2 -L "RECOVERY" ${DEVICE}2
sudo mkfs.exfat -c 32K -L "OPL" ${DEVICE}3
fi
} >> "${INSTALL_LOG}" 2>&1
PARTITION_NUMBER=3
function_make_ps2_dirs
# Finalising recovery:
if [ ! -d "${TOOLKIT_PATH}/storage/hdd/recovery" ]; then
mkdir -p "${TOOLKIT_PATH}/storage/hdd/recovery"
fi
if [ "$(echo ${DEVICE} | grep -o /dev/loop)" = "/dev/loop" ]; then
sudo mount ${DEVICE}p2 "${TOOLKIT_PATH}/storage/hdd/recovery"
else sudo mount ${DEVICE}2 "${TOOLKIT_PATH}/storage/hdd/recovery"
fi
sudo dd if=${DEVICE} bs=128M count=1 status=noxfer 2>> "${INSTALL_LOG}" | xz -z > /tmp/apa_index.xz 2>> "${INSTALL_LOG}"
sudo cp /tmp/apa_index.xz "${TOOLKIT_PATH}/storage/hdd/recovery"
LBA_MAX=$(sudo blockdev --getsize ${DEVICE})
LBA_GPT_BUP=$(echo $(($LBA_MAX-33)))
sudo dd if=${DEVICE} skip=${LBA_GPT_BUP} bs=512 count=33 status=noxfer 2>> "${INSTALL_LOG}" | xz -z > /tmp/gpt_2nd.xz 2>> "${INSTALL_LOG}"
sudo cp /tmp/gpt_2nd.xz "${TOOLKIT_PATH}/storage/hdd/recovery"
sync
sudo umount -l "${TOOLKIT_PATH}/storage/hdd/recovery"
rmdir "${TOOLKIT_PATH}/storage/hdd/recovery"
function_apa_checksum_fix
function_clear_temp
unset LBA_GPT_BUP
unset LBA_MAX
unset MAGIC_NUMBER
unset PARTITION_NUMBER
#/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
# Run the command and capture output
output=$(sudo "${TOOLKIT_PATH}"/helper/HDL\ Dump.elf toc ${DEVICE} 2>&1)
# Check for the word "aborting" in the output
if echo "$output" | grep -q "aborting"; then
echo "Error: APA partition is broken on ${DEVICE}. Install failed." | tee -a "${INSTALL_LOG}"
read -p "Press any key to exit..."
exit 1
fi
if sudo "${TOOLKIT_PATH}"/helper/HDL\ Dump.elf toc "${DEVICE}" | grep -q '__.POPS' && \
sudo "${TOOLKIT_PATH}"/helper/HDL\ Dump.elf toc "${DEVICE}" | grep -q '__linux.8' && \
sudo "${TOOLKIT_PATH}"/helper/HDL\ Dump.elf toc "${DEVICE}" | grep -q '+OPL'; then
echo
echo "POPS, Music and +OPL partitions were created successfully." | tee -a "${INSTALL_LOG}"
sudo "${TOOLKIT_PATH}"/helper/HDL\ Dump.elf toc "${DEVICE}" >> "${INSTALL_LOG}"
else
echo
echo "Error: Some partitions are missing on ${DEVICE}. See log for details." | tee -a "${INSTALL_LOG}"
sudo "${TOOLKIT_PATH}"/helper/HDL\ Dump.elf toc "${DEVICE}" >> "${INSTALL_LOG}"
read -p "Press any key to exit..."
exit 1
fi
# Check if 'OPL' is found in the 'lsblk' output and if it matches the device
if ! lsblk -p -o NAME,LABEL | grep -q "${DEVICE}3"; then
echo "Error: APA-Jail failed on ${DEVICE}." | tee -a "${INSTALL_LOG}"
read -p "Press any key to exit..."
exit 1
fi
echo | tee -a "${INSTALL_LOG}"
echo "PSBBN successfully installed." | tee -a "${INSTALL_LOG}"
read -p "Press any key to exit. "