#!/bin/bash # This code is part of RF Swift by @Penthertz # Author(s): Sรฉbastien Dudek (@FlUxIuS) # Stop the script if any command fails set -euo pipefail GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[0;33m' NC='\033[0m' # No Color check_xhost() { if ! command -v xhost &> /dev/null; then echo -e "${RED}โŒ xhost is not installed on this system. โŒ${NC}" if command -v pacman &> /dev/null; then echo -e "${YELLOW}๐Ÿ“ฆ Installing xorg-xhost using pacman... ๐Ÿ“ฆ${NC}" sudo pacman -Syu --noconfirm xorg-xhost elif command -v apt &> /dev/null; then echo -e "${YELLOW}๐Ÿ“ฆ Installing x11-xserver-utils using apt... ๐Ÿ“ฆ${NC}" sudo apt update sudo apt install -y x11-xserver-utils elif command -v yum &> /dev/null; then echo -e "${YELLOW}๐Ÿ“ฆ Installing xorg-x11-utils using yum... ๐Ÿ“ฆ${NC}" sudo yum install -y xorg-x11-utils else echo -e "${RED}โŒ Unsupported package manager. Please install xhost manually. โŒ${NC}" exit 1 fi echo -e "${GREEN}โœ… xhost installed successfully. โœ…${NC}" else echo -e "${GREEN}โœ… xhost is already installed. Moving on. โœ…${NC}" fi } check_pulseaudio() { if ! command -v pulseaudio &> /dev/null; then echo -e "${RED}โŒ PulseAudio is not installed on this system. โŒ${NC}" if [[ "$OSTYPE" == "darwin"* ]]; then echo -e "${YELLOW}๐ŸŽ Detected macOS. Checking for Homebrew... ๐ŸŽ${NC}" if ! command -v brew &> /dev/null; then echo -e "${RED}โŒ Homebrew is not installed. Please install Homebrew first. โŒ${NC}" echo -e "${YELLOW}โ„น๏ธ You can install Homebrew by running: โ„น๏ธ${NC}" echo -e "${BLUE}๐Ÿบ /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\" ๐Ÿบ${NC}" exit 1 fi echo -e "${YELLOW}๐Ÿ”Š Installing PulseAudio using Homebrew... ๐Ÿ”Š${NC}" brew install pulseaudio elif command -v pacman &> /dev/null; then echo -e "${YELLOW}๐Ÿ”Š Installing PulseAudio using pacman... ๐Ÿ”Š${NC}" sudo pacman -Syu --noconfirm pulseaudio pulseaudio-alsa elif command -v apt &> /dev/null; then echo -e "${YELLOW}๐Ÿ”Š Installing PulseAudio using apt... ๐Ÿ”Š${NC}" sudo apt update sudo apt install -y pulseaudio pulseaudio-utils elif command -v yum &> /dev/null; then echo -e "${YELLOW}๐Ÿ”Š Installing PulseAudio using yum... ๐Ÿ”Š${NC}" sudo yum install -y pulseaudio else echo -e "${RED}โŒ Unsupported package manager. Please install PulseAudio manually. โŒ${NC}" exit 1 fi echo -e "${GREEN}โœ… PulseAudio installed successfully. โœ…${NC}" else echo -e "${GREEN}โœ… PulseAudio is already installed. Moving on. โœ…${NC}" fi if [[ "$OSTYPE" == "darwin"* ]]; then echo -e "${YELLOW}๐ŸŽ Detected macOS. PulseAudio server will not be started. ๐ŸŽ${NC}" return fi echo -e "${YELLOW}๐ŸŽต Starting PulseAudio... ๐ŸŽต${NC}" pulseaudio --check &> /dev/null || pulseaudio --start echo -e "${GREEN}๐ŸŽง PulseAudio is running. ๐ŸŽง${NC}" } check_curl() { if ! command -v curl &> /dev/null; then echo -e "${RED}โŒ curl is not installed on this system. โŒ${NC}" if [ "$(uname -s)" == "Darwin" ]; then echo -e "${YELLOW}๐ŸŽ Attempting to install curl on macOS using Homebrew... ๐ŸŽ${NC}" if ! command -v brew &> /dev/null; then echo -e "${RED}โŒ Homebrew is not installed. Please install Homebrew first. โŒ${NC}" echo "Visit https://brew.sh/ for installation instructions." exit 1 fi brew install curl elif [ "$(uname -s)" == "Linux" ]; then if command -v apt &> /dev/null; then echo -e "${YELLOW}๐Ÿง Attempting to install cURL using apt... ๐Ÿง${NC}" sudo apt update sudo apt install -y curl elif command -v yum &> /dev/null; then echo -e "${YELLOW}๐Ÿง Attempting to install cURL using yum... ๐Ÿง${NC}" sudo yum install -y curl elif command -v pacman &> /dev/null; then echo -e "${YELLOW}๐Ÿง Attempting to install cURL using pacman... ๐Ÿง${NC}" sudo pacman -Syu curl else echo -e "${RED}โŒ Unable to detect package manager. Please install cURL manually. โŒ${NC}" exit 1 fi else echo -e "${RED}โŒ Unsupported operating system. Please install cURL manually. โŒ${NC}" exit 1 fi echo -e "${GREEN}โœ… curl installed successfully. โœ…${NC}" else echo -e "${GREEN}โœ… curl is already installed. Moving on. โœ…${NC}" fi } check_docker() { # Check if this is a Steam Deck installation (Linux only) if [ "$(uname -s)" == "Linux" ]; then echo -e "${YELLOW}๐ŸŽฎ Are you installing on a Steam Deck? (yes/no) ๐ŸŽฎ${NC}" read -p "Choose an option: " steamdeck_install if [ "$steamdeck_install" == "yes" ]; then install_docker_steamdeck return fi fi # Check if Docker is installed if ! command -v docker &> /dev/null; then echo -e "${RED}๐Ÿณ Docker is not installed. Do you want to install it now? (yes/no) ๐Ÿณ${NC}" read -p "Choose an option: " install_docker if [ "$install_docker" == "yes" ]; then install_docker_standard else echo -e "${RED}โŒ Docker is required to proceed. Exiting. โŒ${NC}" exit 1 fi else echo -e "${GREEN}โœ… Docker is already installed. Moving on. โœ…${NC}" # This part only runs in the full check_docker function if [ "${FUNCNAME[0]}" == "check_docker" ]; then install_buildx install_docker_compose fi fi } # Create an alias for the user-only version check_docker_user_only() { check_docker } install_docker_standard() { arch=$(uname -m) os=$(uname -s) if [ "$os" == "Darwin" ]; then # macOS installation using Homebrew if ! command -v brew &> /dev/null; then echo -e "${RED}โŒ Homebrew is not installed. Please install Homebrew first. โŒ${NC}" echo "Visit https://brew.sh/ for installation instructions." exit 1 fi echo -e "${YELLOW}๐ŸŽ Installing Docker using Homebrew... ๐ŸŽ${NC}" brew install --cask docker echo -e "${GREEN}โœ… Docker installed successfully on macOS. โœ…${NC}" echo -e "${YELLOW}โ„น๏ธ Please launch Docker from Applications to start the Docker daemon. โ„น๏ธ${NC}" elif [ "$os" == "Linux" ]; then # Make sure os-release exists if [ ! -f /etc/os-release ]; then echo -e "${YELLOW}๐Ÿง Cannot determine Linux distribution. Using standard Docker installation. ๐Ÿง${NC}" sudo curl -fsSL "https://get.docker.com/" | sh sudo systemctl start docker sudo systemctl enable docker echo -e "${GREEN}โœ… Docker installed successfully. โœ…${NC}" install_buildx install_docker_compose return fi distro=$(grep "^ID=" /etc/os-release | cut -d= -f2 | tr -d '"') if [ "$distro" == "arch" ] || [ "$distro" == "archlinux" ]; then # Arch Linux installation using pacman echo -e "${YELLOW}๐Ÿน Installing Docker for Arch Linux using pacman... ๐Ÿน${NC}" sudo pacman -Sy --noconfirm docker sudo systemctl start docker sudo systemctl enable docker echo -e "${GREEN}โœ… Docker installed successfully on Arch Linux. โœ…${NC}" elif command -v apt &> /dev/null && [ "$distro" == "debian" ] || [ "$distro" == "ubuntu" ] || [ "$distro" == "kali" ]; then # Debian-based installation using apt echo -e "${YELLOW}๐Ÿง Installing Docker for Debian-based systems using apt... ๐Ÿง${NC}" sudo apt update sudo apt install -y docker.io sudo systemctl start docker sudo systemctl enable docker echo -e "${GREEN}โœ… Docker installed successfully on Debian-based system. โœ…${NC}" elif [ "$arch" == "riscv64" ]; then # riscv64 installation using apt if command -v apt &> /dev/null; then echo -e "${YELLOW}๐Ÿ”ง Installing Docker for riscv64 using apt... ๐Ÿ”ง${NC}" sudo apt update sudo apt install -y docker.io sudo systemctl start docker sudo systemctl enable docker echo -e "${GREEN}โœ… Docker installed successfully on riscv64. โœ…${NC}" else echo -e "${RED}โŒ apt is not available on this system. Unable to install Docker for riscv64. โŒ${NC}" exit 1 fi else # Standard Linux installation echo -e "${YELLOW}๐Ÿง Installing Docker for Linux... ๐Ÿง${NC}" sudo curl -fsSL "https://get.docker.com/" | sh sudo systemctl start docker sudo systemctl enable docker echo -e "${GREEN}โœ… Docker installed successfully. โœ…${NC}" fi install_buildx install_docker_compose else echo -e "${RED}โŒ Unsupported operating system: $os โŒ${NC}" exit 1 fi } install_docker_steamdeck() { # Installation steps for Docker on Steam Deck echo -e "${YELLOW}[+] ๐ŸŽฎ Disabling read-only mode on Steam Deck ๐ŸŽฎ${NC}" sudo steamos-readonly disable echo -e "${YELLOW}[+] ๐Ÿ”‘ Initializing pacman keyring ๐Ÿ”‘${NC}" sudo pacman-key --init sudo pacman-key --populate archlinux echo -e "${YELLOW}[+] ๐Ÿณ Installing Docker ๐Ÿณ${NC}" sudo pacman -Syu docker echo -e "${YELLOW}[+] ๐Ÿ”’ Re-enabling read-only mode on Steam Deck ๐Ÿ”’${NC}" sudo steamos-readonly enable install_docker_compose_steamdeck } install_docker_compose_steamdeck() { echo -e "${YELLOW}[+] ๐Ÿงฉ Installing Docker Compose v2 plugin ๐Ÿงฉ${NC}" DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} mkdir -p $DOCKER_CONFIG/cli-plugins sudo curl -SL https://github.com/docker/compose/releases/download/v2.36.0/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose echo -e "${YELLOW}[+] ๐Ÿ‘ฅ Adding 'deck' user to Docker user group ๐Ÿ‘ฅ${NC}" sudo usermod -a -G docker deck echo -e "${GREEN}โœ… Docker and Docker Compose v2 installed successfully on Steam Deck. โœ…${NC}" } install_buildx() { arch=$(uname -m) os=$(uname -s | tr '[:upper:]' '[:lower:]') # Convert OS to lowercase version="v0.23.0" # Map architecture to buildx naming convention case "$arch" in x86_64|amd64) arch="amd64";; arm64|aarch64) arch="arm64";; riscv64) arch="riscv64";; *) printf "${RED}โŒ Unsupported architecture: \"%s\" -> Unable to install Buildx โŒ${NC}\n" "$arch" >&2; exit 2;; esac # Check if Buildx is already installed if ! sudo docker buildx version &> /dev/null; then echo -e "${YELLOW}[+] ๐Ÿ—๏ธ Installing Docker Buildx ๐Ÿ—๏ธ${NC}" # Additional setup for Linux if [ "$os" = "linux" ]; then sudo docker run --privileged --rm tonistiigi/binfmt --install all fi # Create CLI plugins directory if it doesn't exist mkdir -p ~/.docker/cli-plugins/ # Determine the Buildx binary URL based on OS and architecture buildx_url="https://github.com/docker/buildx/releases/download/${version}/buildx-${version}.${os}-${arch}" # Download the Buildx binary echo -e "${YELLOW}[+] ๐Ÿ“ฅ Downloading Buildx from ${buildx_url} ๐Ÿ“ฅ${NC}" sudo curl -sSL "$buildx_url" -o "${HOME}/.docker/cli-plugins/docker-buildx" # Make the binary executable sudo chmod +x "${HOME}/.docker/cli-plugins/docker-buildx" echo -e "${GREEN}โœ… Docker Buildx installed successfully. โœ…${NC}" else echo -e "${GREEN}โœ… Docker Buildx is already installed. Moving on. โœ…${NC}" fi } install_docker_compose() { arch=$(uname -m) os=$(uname -s | tr '[:upper:]' '[:lower:]') # Convert OS to lowercase version="v2.36.0" # Map architecture to Docker Compose naming convention case "$arch" in x86_64|amd64) arch="x86_64";; arm64|aarch64) arch="aarch64";; riscv64) arch="riscv64";; *) printf "${RED}โŒ Unsupported architecture: \"%s\" -> Unable to install Docker Compose โŒ${NC}\n" "$arch" >&2; exit 2;; esac # Check if Docker Compose is already installed if ! sudo docker compose version &> /dev/null; then echo -e "${YELLOW}[+] ๐Ÿงฉ Installing Docker Compose v2 ๐Ÿงฉ${NC}" # Determine the Docker Compose binary URL based on OS and architecture compose_url="https://github.com/docker/compose/releases/download/${version}/docker-compose-${os}-${arch}" # Set the Docker CLI plugins directory DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} mkdir -p $DOCKER_CONFIG/cli-plugins # Download the Docker Compose binary echo -e "${YELLOW}[+] ๐Ÿ“ฅ Downloading Docker Compose from ${compose_url} ๐Ÿ“ฅ${NC}" sudo curl -sSL "$compose_url" -o "$DOCKER_CONFIG/cli-plugins/docker-compose" # Make the binary executable sudo chmod +x "$DOCKER_CONFIG/cli-plugins/docker-compose" echo -e "${GREEN}โœ… Docker Compose v2 installed successfully. โœ…${NC}" else echo -e "${GREEN}โœ… Docker Compose v2 is already installed. Moving on. โœ…${NC}" fi } install_go() { if command -v go &> /dev/null; then echo -e "${GREEN}โœ… golang is already installed and in PATH. Moving on. โœ…${NC}" return 0 fi if [ -x "/usr/local/go/bin/go" ]; then echo -e "${GREEN}โœ… golang is already installed in /usr/local/go/bin. Moving on. โœ…${NC}" export PATH=$PATH:/usr/local/go/bin return 0 fi [ -d thirdparty ] || mkdir thirdparty cd thirdparty arch=$(uname -m) os=$(uname -s | tr '[:upper:]' '[:lower:]') # Normalize OS name to lowercase prog="" version="1.24.3" # Map architecture and OS to Go binary tar.gz naming convention case "$arch" in x86_64|amd64) arch="amd64";; i?86) arch="386";; arm64|aarch64) arch="arm64";; riscv64) arch="riscv64";; *) printf "${RED}โŒ Unsupported architecture: \"%s\" -> Unable to install Go โŒ${NC}\n" "$arch" >&2; exit 2;; esac case "$os" in linux|darwin) prog="go${version}.${os}-${arch}.tar.gz";; *) printf "${RED}โŒ Unsupported OS: \"%s\" -> Unable to install Go โŒ${NC}\n" "$os" >&2; exit 2;; esac # Download and install Go echo -e "${YELLOW}[+] ๐Ÿ“ฅ Downloading Go from https://go.dev/dl/${prog} ๐Ÿ“ฅ${NC}" wget "https://go.dev/dl/${prog}" sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf $prog export PATH=$PATH:/usr/local/go/bin cd .. rm -rf thirdparty echo -e "${GREEN}โœ… Go installed successfully. โœ…${NC}" } building_rfswift() { cd go/rfswift/ echo -e "${YELLOW}๐Ÿ”จ Building RF Swift Go Project... ๐Ÿ”จ${NC}" go build . mv rfswift ../.. # moving compiled file to project's root cd ../.. echo -e "${GREEN}โœ… RF Swift Go Project built successfully. โœ…${NC}" } build_docker_image() { # Prompt the user to choose the architecture(s) echo -e "${YELLOW}๐Ÿ—๏ธ Select the architecture(s) to build for: ๐Ÿ—๏ธ${NC}" echo "1) amd64 ๐Ÿ’ป" echo "2) arm64/v8 ๐Ÿ“ฑ" echo "3) riscv64 ๐Ÿ”ฌ" read -p "Choose an option (1, 2, or 3): " arch_option case "$arch_option" in 1) PLATFORM="linux/amd64" ;; 2) PLATFORM="linux/arm64/v8" ;; 3) PLATFORM="linux/riscv64" ;; *) echo -e "${RED}โŒ Invalid option. Exiting. โŒ${NC}" exit 1 ;; esac # Set default values DEFAULT_IMAGE="myrfswift:latest" DEFAULT_DOCKERFILE="Dockerfile" # Prompt the user for input with default values read -p "Enter you ressources directory (where configs, and scripts are placed): " ressourcesdir read -p "Enter image tag value (default: $DEFAULT_IMAGE): " imagename read -p "Enter value for Dockerfile to use (default: $DEFAULT_DOCKERFILE): " dockerfile # Use default values if variables are empty imagename=${imagename:-$DEFAULT_IMAGE} dockerfile=${dockerfile:-$DEFAULT_DOCKERFILE} echo -e "${YELLOW}[+] ๐Ÿณ Building the Docker container for $PLATFORM ๐Ÿณ${NC}" sudo docker buildx build --platform $PLATFORM -t $imagename -f $dockerfile ressourcesdir } pull_docker_image() { sudo ./rfswift images remote read -p "Enter the image tag to pull (default: penthertz/rfswift:corebuild): " pull_image pull_image=${pull_image:-penthertz/rfswift:corebuild} echo -e "${YELLOW}[+] ๐Ÿ“ฅ Pulling the Docker image ๐Ÿ“ฅ${NC}" sudo docker pull $pull_image } install_binary_alias() { # First, ask where to install the binary echo -e "${YELLOW}๐Ÿ“ฆ Where would you like to install the rfswift binary? ๐Ÿ“ฆ${NC}" echo -e "1) /usr/local/bin (requires sudo privileges) ๐Ÿ”" echo -e "2) $HOME/.rfswift/bin/ (user-only installation) ๐Ÿ‘ค" read -p "Choose an option (1 or 2): " install_location # Set the binary installation path based on user's choice if [ "$install_location" == "1" ]; then INSTALL_DIR="/usr/local/bin" BINARY_PATH="$INSTALL_DIR/rfswift" SUDO_CMD="sudo" echo -e "${YELLOW}[+] ๐Ÿ’ป Installing to system location ($INSTALL_DIR) ๐ŸŒ${NC}" else INSTALL_DIR="$HOME/.rfswift/bin" BINARY_PATH="$INSTALL_DIR/rfswift" SUDO_CMD="" echo -e "${YELLOW}[+] ๐Ÿ  Installing to user location ($INSTALL_DIR) ๐Ÿ‘ค${NC}" # Create the directory if it doesn't exist mkdir -p "$INSTALL_DIR" fi # Copy the binary to the installation directory SOURCE_BINARY=$(pwd)/rfswift if [ -f "$SOURCE_BINARY" ]; then echo -e "${YELLOW}[+] ๐Ÿ“‹ Copying binary to $INSTALL_DIR ๐Ÿ“‹${NC}" $SUDO_CMD cp "$SOURCE_BINARY" "$BINARY_PATH" $SUDO_CMD chmod +x "$BINARY_PATH" else echo -e "${RED}โŒ Binary not found at $SOURCE_BINARY. Make sure the binary is built correctly. โŒ${NC}" exit 1 fi # Ask if user wants to create an alias read -p "Do you want to create an alias for the binary? (yes/no): " create_alias if [ "$create_alias" == "yes" ]; then read -p "Enter the alias name for the binary (default: rfswift): " alias_name alias_name=${alias_name:-rfswift} # Detect the current user and home directory if [ -n "${SUDO_USER-}" ]; then CURRENT_USER="$SUDO_USER" HOME_DIR=$(eval echo "~$SUDO_USER") else CURRENT_USER=$(whoami) HOME_DIR=$HOME fi # Detect the shell for the current user SHELL_NAME=$(basename "$SHELL") # Choose the alias file based on the detected shell case "$SHELL_NAME" in bash) if [[ "$OSTYPE" == "darwin"* ]]; then ALIAS_FILE="$HOME_DIR/.bash_profile" # macOS else ALIAS_FILE="$HOME_DIR/.bashrc" # Linux fi ;; zsh) ALIAS_FILE="$HOME_DIR/.zshrc" ;; *) ALIAS_FILE="$HOME_DIR/.${SHELL_NAME}rc" ;; esac # Create the alias file if it doesn't exist if [[ ! -f "$ALIAS_FILE" ]]; then echo -e "${YELLOW}[+] ๐Ÿ“ Alias file $ALIAS_FILE does not exist. Creating it... ๐Ÿ†•${NC}" touch "$ALIAS_FILE" fi # Check if the alias already exists in the config file ALIAS_EXISTS=false ALIAS_NEEDS_UPDATE=false if [ -f "$ALIAS_FILE" ]; then # Extract the current path if the alias already exists EXISTING_ALIAS=$(grep "^alias $alias_name=" "$ALIAS_FILE" 2>/dev/null) if [ -n "$EXISTING_ALIAS" ]; then ALIAS_EXISTS=true # Extract the path from the existing alias EXISTING_PATH=$(echo "$EXISTING_ALIAS" | sed -E "s/^alias $alias_name='?([^']*)'?$/\1/") if [ "$EXISTING_PATH" != "$BINARY_PATH" ]; then ALIAS_NEEDS_UPDATE=true echo -e "${YELLOW}[!] โš ๏ธ Alias '$alias_name' already exists but points to a different path: โš ๏ธ${NC}" echo -e "${YELLOW} Current: $EXISTING_PATH${NC}" echo -e "${YELLOW} New: $BINARY_PATH${NC}" read -p "Do you want to update the alias to the new path? (yes/no): " update_alias if [ "$update_alias" == "yes" ]; then # Remove the existing alias line sed -i.bak "/^alias $alias_name=/d" "$ALIAS_FILE" # Add the new alias echo "alias $alias_name='$BINARY_PATH'" >> "$ALIAS_FILE" echo -e "${GREEN}โœ… Alias '$alias_name' updated successfully. โœ…${NC}" else echo -e "${GREEN}๐Ÿ‘ Keeping existing alias configuration. ๐Ÿ‘${NC}" fi else echo -e "${GREEN}โœ… Alias '$alias_name' already exists with the correct path. โœ…${NC}" fi fi fi # Only add the alias if it doesn't exist and doesn't need an update if [ "$ALIAS_EXISTS" = false ] && [ "$ALIAS_NEEDS_UPDATE" = false ]; then # Add the alias to the appropriate shell configuration file for the user echo "alias $alias_name='$BINARY_PATH'" >> "$ALIAS_FILE" echo -e "${GREEN}โœ… Alias '$alias_name' installed successfully! โœ…${NC}" fi # Provide instructions to apply changes if [ "$SHELL_NAME" = "zsh" ]; then echo -e "${YELLOW}๐Ÿ”„ Zsh configuration updated. Please restart your terminal or run 'exec zsh' to apply the changes. ๐Ÿ”„${NC}" elif [ "$SHELL_NAME" = "bash" ]; then # Source the Bash configuration file if [ -f "$ALIAS_FILE" ]; then echo -e "${YELLOW}๐Ÿ”„ Bash configuration updated. Please run 'source $ALIAS_FILE' to apply the changes. ๐Ÿ”„${NC}" fi else echo -e "${YELLOW}๐Ÿ”„ Please restart your terminal or source the ${ALIAS_FILE} manually to apply the alias. ๐Ÿ”„${NC}" fi # If installed to user directory, add path to PATH if needed if [ "$install_location" == "2" ]; then # Check if the directory is already in PATH if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then echo -e "${YELLOW}[+] ๐Ÿ”€ Adding $INSTALL_DIR to your PATH ๐Ÿ”€${NC}" echo "export PATH=\$PATH:$INSTALL_DIR" >> "$ALIAS_FILE" echo -e "${GREEN}โœ… PATH updated successfully. Please restart your terminal or source your shell config file. โœ…${NC}" fi fi else echo -e "${GREEN}โญ๏ธ Skipping alias creation. โญ๏ธ${NC}" # If user-only installation and no alias, still add to PATH if needed if [ "$install_location" == "2" ]; then # Detect the shell configuration file if [[ "$OSTYPE" == "darwin"* ]]; then [ -f "$HOME/.bash_profile" ] && RC_FILE="$HOME/.bash_profile" || RC_FILE="$HOME/.profile" [ -f "$HOME/.zshrc" ] && [ "$SHELL" = *"zsh"* ] && RC_FILE="$HOME/.zshrc" else [ -f "$HOME/.bashrc" ] && RC_FILE="$HOME/.bashrc" || RC_FILE="$HOME/.profile" [ -f "$HOME/.zshrc" ] && [ "$SHELL" = *"zsh"* ] && RC_FILE="$HOME/.zshrc" fi # Check if the directory is already in PATH if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then echo -e "${YELLOW}[+] ๐Ÿ”€ Would you like to add $INSTALL_DIR to your PATH? (yes/no) ๐Ÿ”€${NC}" read -p "Choose an option: " add_to_path if [ "$add_to_path" == "yes" ]; then echo "export PATH=\$PATH:$INSTALL_DIR" >> "$RC_FILE" echo -e "${GREEN}โœ… PATH updated in $RC_FILE. Please restart your terminal or run 'source $RC_FILE'. โœ…${NC}" else echo -e "${YELLOW}โ„น๏ธ Note: You'll need to run $BINARY_PATH using its full path. โ„น๏ธ${NC}" fi fi fi fi echo -e "${GREEN}๐ŸŽ‰ Installation complete! You can now use rfswift. ๐ŸŽ‰${NC}" } check_config_file() { # Determine config file location based on OS if [[ "$OSTYPE" == "darwin"* ]]; then CONFIG_DIR="$HOME/Library/Application Support/rfswift" else CONFIG_DIR="$HOME/.config/rfswift" fi CONFIG_FILE="$CONFIG_DIR/config.ini" echo -e "${YELLOW}๐Ÿ” Checking configuration file at: $CONFIG_FILE ๐Ÿ”${NC}" # Check if config file exists if [ ! -f "$CONFIG_FILE" ]; then echo -e "${YELLOW}๐Ÿ“ Config file not found at $CONFIG_FILE ๐Ÿ“${NC}" echo -e "${GREEN}โœจ A new config file will be created on first run ;) โœจ${NC}" return 0 fi # Define required sections and keys - without using declare -A which is not supported in older bash GENERAL_KEYS="imagename repotag" CONTAINER_KEYS="shell bindings network exposedports portbindings x11forward xdisplay extrahost extraenv devices privileged caps seccomp cgroups" AUDIO_KEYS="pulse_server" missing_fields=0 current_section="" # For debugging echo -e "${YELLOW}๐Ÿ”Ž Scanning config file for keys... ๐Ÿ”Ž${NC}" # Read config file line by line while IFS= read -r line || [ -n "$line" ]; do # Trim leading/trailing whitespace line=$(echo "$line" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') # Skip empty lines and comments if [[ -z "$line" || "$line" == \#* ]]; then continue fi # Check if line is a section header if [[ "$line" =~ ^\[([a-zA-Z0-9_]+)\]$ ]]; then current_section="${BASH_REMATCH[1]}" echo -e "${YELLOW}๐Ÿ“‚ Found section: [$current_section] ๐Ÿ“‚${NC}" continue fi # Check if line contains a key (regardless of value) if [[ "$line" =~ ^([a-zA-Z0-9_]+)[[:space:]]*= ]]; then key="${BASH_REMATCH[1]}" echo -e "${GREEN}๐Ÿ”‘ Found key: $key in section [$current_section] ๐Ÿ”‘${NC}" # Remove the key from the required keys list based on section if [[ "$current_section" == "general" ]]; then GENERAL_KEYS=$(echo "$GENERAL_KEYS" | sed -E "s/(^| )$key( |$)/ /g" | tr -s ' ' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') elif [[ "$current_section" == "container" ]]; then CONTAINER_KEYS=$(echo "$CONTAINER_KEYS" | sed -E "s/(^| )$key( |$)/ /g" | tr -s ' ' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') elif [[ "$current_section" == "audio" ]]; then AUDIO_KEYS=$(echo "$AUDIO_KEYS" | sed -E "s/(^| )$key( |$)/ /g" | tr -s ' ' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') fi fi done < "$CONFIG_FILE" # Debug: show remaining required keys after parsing echo -e "${YELLOW}๐Ÿ“‹ Remaining required keys in [general]: ${GENERAL_KEYS} ๐Ÿ“‹${NC}" echo -e "${YELLOW}๐Ÿ“‹ Remaining required keys in [container]: ${CONTAINER_KEYS} ๐Ÿ“‹${NC}" echo -e "${YELLOW}๐Ÿ“‹ Remaining required keys in [audio]: ${AUDIO_KEYS} ๐Ÿ“‹${NC}" # Check for missing fields in each section if [[ -n "$GENERAL_KEYS" ]]; then echo -e "${RED}โ— Missing keys in [general] section: โ—${NC}" for field in $GENERAL_KEYS; do echo -e " - ${YELLOW}๐Ÿ”ด $field ๐Ÿ”ด${NC}" missing_fields=$((missing_fields + 1)) done fi if [[ -n "$CONTAINER_KEYS" ]]; then echo -e "${RED}โ— Missing keys in [container] section: โ—${NC}" for field in $CONTAINER_KEYS; do echo -e " - ${YELLOW}๐Ÿ”ด $field ๐Ÿ”ด${NC}" missing_fields=$((missing_fields + 1)) done fi if [[ -n "$AUDIO_KEYS" ]]; then echo -e "${RED}โ— Missing keys in [audio] section: โ—${NC}" for field in $AUDIO_KEYS; do echo -e " - ${YELLOW}๐Ÿ”ด $field ๐Ÿ”ด${NC}" missing_fields=$((missing_fields + 1)) done fi if [ $missing_fields -gt 0 ]; then echo -e "${RED}โš ๏ธ WARNING: $missing_fields required keys are missing from your config file. โš ๏ธ${NC}" echo -e "${YELLOW}๐Ÿ’ก You should either: ๐Ÿ’ก${NC}" echo -e " 1. ๐Ÿ“ Add the missing keys to $CONFIG_FILE (values can be empty) ๐Ÿ“" echo -e " 2. ๐Ÿ”„ Rename or delete $CONFIG_FILE to generate a fresh config with defaults ๐Ÿ”„" return 1 else echo -e "${GREEN}โœ… Config file validation successful! All required keys present. โœ…${NC}" return 0 fi # Add option to show the config file content for debugging if [ "$1" = "--debug" ]; then echo -e "${YELLOW}๐Ÿ” === Config File Content ==== ๐Ÿ”${NC}" cat "$CONFIG_FILE" echo -e "${YELLOW}๐Ÿ” ========================== ๐Ÿ”${NC}" fi } display_rainbow_logo_animated() { # Define an array of colors for rainbow effect colors=( '\033[1;31m' # Red '\033[1;33m' # Orange/Yellow '\033[1;32m' # Green '\033[1;36m' # Cyan '\033[1;34m' # Blue '\033[1;35m' # Purple ) NC='\033[0m' # No Color # The logo text as an array of lines logo=( " 888~-_ 888~~ ,d88~~\\ ,e, 88~\\ d8 " " 888 \\ 888___ 8888 Y88b e / \" *888*_ *d88*_ " " 888 | 888 'Y88b Y88b d8b / 888 888 888 " " 888 / 888 'Y88b, Y888/Y88b/ 888 888 888 " " 888_-~ 888 8888 Y8/ Y8/ 888 888 888 " " 888 ~-_ 888 \\__88P' Y Y 888 888 \"88_/" ) # Clear the screen for better presentation clear # First, print each line with its own color for i in {0..5}; do echo -e "${colors[$i]}${logo[$i]}${NC}" sleep 0.1 # Small delay between lines done sleep 0.5 # Pause before the animation # Now animate by cycling through colors if [ -t 1 ]; then # Only run animation if in an interactive terminal for cycle in {1..3}; do # Run the cycle 3 times # Move cursor back up 6 lines to the start of the logo for i in {1..6}; do echo -en "\033[1A" done # Print each line with the next color in the cycle for i in {0..5}; do color_index=$(( (i + cycle) % 6 )) echo -e "${colors[$color_index]}${logo[$i]}${NC}" done sleep 0.3 # Wait before the next cycle done fi # Add a tagline echo -e "\n${colors[5]}๐Ÿ”ฅ RF Swift by @Penthertz - Radio Frequency Swiss Army Knife ๐Ÿ”ฅ${NC}\n" # Add a slight delay before continuing sleep 0.5 }