#!/bin/bash unset IFS export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH" # Prompt user until they type Y/y or N/n # Calling: # prompt_yesno prompt_yesno() { local input="" while true; do printf "%s" "(Y/n): " read input if [ "$input" = "" ] || [ "$input" = "Y" ] || [ "$input" = "y" ]; then return 0 fi if [ "$input" = "N" ] || [ "$input" = "n" ]; then return 1 fi done } if [ "$BASH_VERSION" = "" ]; then echo Required bash scripting environment not detected. You are likely running with /bin/sh. Rerun with /bin/bash? if prompt_yesno; then /bin/bash "$0"; fi exit 0 fi if [ $UID -ne 0 ]; then # Clear out any existing credentials so the user always gets a prompt sudo -K echo "Type your password below to give ScreenConnect permission to install: " echo "(You can also Ctrl-C to exit and re-run the script as root)" sudo "$0" exit 0 fi INSTALL_SCRIPT_PATH="$(dirname "$0")" INSTALL_DIRECTORY="$INSTALL_SCRIPT_PATH/Installer" SCREENCONNECT_DIRECTORY="$INSTALL_SCRIPT_PATH/ScreenConnect" MIN_UPGRADE_VERSION="5.3" source "$INSTALL_DIRECTORY/functions.sh" echo "" echo "Welcome to the ScreenConnect Installer" echo "" echo "The installer will do these things:" echo "1) Prompt you for installation options" echo "2) Display a list of actions to be taken" echo "3) Prompt you for execution of the actions" echo "4) Execute the actions" find "$INSTALL_DIRECTORY/Distributions" -name "*.sh" -not -name ".*" | sort > /tmp/distros while read distroFile; do source "$distroFile" if is_distro_valid; then break; fi done < /tmp/distros rm /tmp/distros demand_system_compatible # This is filled by the base dependencies function (or whatever a script adds in dependency_check() # It consists of dependencies that need to be addressed in the form dependency:reason problematic_dependencies=() # These actions are used by the build_install_actions script installer_actions=() installer_action_descriptions=() # Execute the actual dependency check, this will fill problematic_dependencies dependency_check # Loop through the missing dependencies and build the installer action and description arrays for i in ${!problematic_dependencies[*]} do # Each element is dependency:reason dependency_parts=($(echo "${problematic_dependencies[$i]}")) build_dependency_action "${dependency_parts[0]}" if [ $? == 1 ]; then # Return value of 1 means a build action was added, so remove the element from the array unset problematic_dependencies[$i] fi done if [ ${#problematic_dependencies[*]} -gt 0 ]; then echo "" echo "We were unable to resolve these dependencies:" is_a_dependency_critical=0 for i in ${!problematic_dependencies[*]} do echo ${problematic_dependencies[$i]} (echo ${problematic_dependencies[$i]} | grep "(critical)" > /dev/null) && is_a_dependency_critical=1 done if [ $is_a_dependency_critical -eq 1 ]; then echo "" echo "One or more critical dependencies could not be resolved. Installation cannot continue." exit 1 fi echo "" echo "None of these are required. Would you like to continue?" if ! prompt_yesno; then echo "Exiting due to unresolved dependencies..." exit 1 fi fi # Prompt user for options installation_directory="/opt/ScreenConnect" # Let's use the new lower case one unless the old one exists # OS X's filesystem is case-insensitive, so a simple test -d $installation_directory won't distinguish between /opt/ScreenConnect and /opt/screenconnect # However, if you make bash do filename expansion, it will distinguish between them # Surrounding every non-slash character following a slash with [] will result in /opt/ScreenConnect if it does exist and /[o]pt/[S]creenConnect if it doesn't # The right-hand expression in the test must be unquoted for this wildcard expansion to happen if [ $installation_directory != $(echo "$installation_directory" | sed 's,/\([^/]\),/[\1],g') ]; then installation_directory="/opt/screenconnect"; fi while true; do echo "" echo "Where would you like to install ScreenConnect?" printf "%s" "[$installation_directory] " read input if [ "$input" == "" ]; then break; elif [[ "$input" == "/"* ]]; then installation_directory=$input break; else echo "" echo "Invalid location" fi done installer="`cd "$(dirname $0)"; pwd`/$(basename $0)" # installer full path if [[ $installer == $installation_directory/* ]]; then echo "The ScreenConnect installation directory cannot contain the installer ('$installer'). Please move the installer or choose a different location to install ScreenConnect and rerun this script." exit 1 fi is_upgrade=0 if test -d "$installation_directory"; then is_upgrade=1; fi if [ $is_upgrade -eq 1 ]; then old_version=$(get_product_version "$installation_directory") if ! is_version_a_gte_version_b "$old_version" "$MIN_UPGRADE_VERSION"; then echo "" echo "This package only supports upgrading from ScreenConnect $MIN_UPGRADE_VERSION or higher. Your version was detected as ${old_version}. Please upgrade and rerun this package." exit 1 fi new_version=$(get_product_version "$SCREENCONNECT_DIRECTORY") if ! is_version_a_gte_version_b "$new_version" "$old_version"; then echo "" echo "Detected existing installation at version $old_version. Cannot downgrade to $new_version." exit 1 fi echo "" echo "It appears that there is already an installation at $installation_directory ($old_version)" echo "Would you like to upgrade?" if ! prompt_yesno; then echo "Installation directory already exists, and you chose not to upgrade it. Please erase the existing installation to perform a fresh install in $installation_directory or rerun this script and choose to upgrade" exit 1 fi fi # Setup environment because we have to call mono export PATH=$installation_directory/App_Runtime/bin:$PATH export MONO_PATH=$installation_directory/App_Runtime/lib export MONO_CFG_DIR=$installation_directory/App_Runtime/etc # Find init.d or whatever is appropriate for this distro initialize_startup_directory_information service_name="" # Stop any running services and remove any existing service startup scripts # (That point to the install folder) if upgrading # This also gets the service name if [ $is_upgrade -eq 1 ]; then service_names=() get_existing_service_names if [ ${#service_names[*]} -gt 0 ]; then for cur_service_name in ${service_names[*]} do build_stop_and_remove_service_action "$cur_service_name" done service_name=${service_names[0]} fi fi if [ "$service_name" == "" ]; then service_name=$(basename "$installation_directory" | tr "[A-Z]" "[a-z]") fi # Determining name of init.d script / service name while true; do echo "" echo "What would you like as the service name for this ScreenConnect installation?" printf "%s" "[$service_name] " read input if ! [[ "$input" =~ ^[a-zA-Z0-9_\-]*$ ]]; then echo "" echo "Service name can only contain letters, numbers, underscores, and hyphens" elif [ "$input" != "" ]; then service_name=$input break else break fi done backup_mtime_unprefixed_reference_file_name=Core.dll backup_mtime_leeway_seconds=60 # Build up a list of what we need to do # Back up files if upgrading if [ $is_upgrade -eq 1 ]; then installer_actions[${#installer_actions[*]}]="make_backup" installer_action_descriptions[${#installer_action_descriptions[*]}]="Back up the existing configuration" fi # Run distribution-specific function to add the build actions to do startup scripts build_startup_actions mono_executable_file_path=$(get_mono_executable_file_path "$INSTALL_DIRECTORY") if [ "$mono_executable_file_path" = "" ]; then echo "" echo "Could not find a suitable version of runtime executable for your system. This could be due to an unsupported instruction set. This could also be due to wiping of the execute bits during extraction of the tarball when /tmp is mounted with noexec." exit 1 fi # Copy installation files installer_actions[${#installer_actions[*]}]="copy_installation_files" installer_action_descriptions[${#installer_action_descriptions[*]}]="Copy files into $installation_directory" # Determine configuration for xsl transform configuration="Release" if ls "$SCREENCONNECT_DIRECTORY"/Bin/*.mdb &>/dev/null; then configuration="Debug" fi # Restore backed up files if upgrading if [ $is_upgrade -eq 1 ]; then installer_actions[${#installer_actions[*]}]="restore_backup" installer_action_descriptions[${#installer_action_descriptions[*]}]="Restore backed up configuration" fi # Do the transforms installer_actions[${#installer_actions[*]}]="transform_configuration_files" installer_action_descriptions[${#installer_action_descriptions[*]}]="Transform configuration files" # Start screenconnect build_start_service_action # Confirm the what we're going to do echo "" echo "The installation will perform the following actions:" for i in ${!installer_action_descriptions[*]} do echo "- ${installer_action_descriptions[i]}" done echo "" echo "Do you want to install ScreenConnect?" if prompt_yesno; then echo "" # Do the install for i in ${!installer_actions[*]} do echo "Running '${installer_action_descriptions[i]}'..." eval ${installer_actions[i]} done echo "" echo "Installation complete!" echo "" echo "Trying to figure out the best URL for you to use..." echo "" launch_web_page "$(mono "$installation_directory/Bin/ScreenConnect.Service.exe" launch host)" echo "" exit 0 else echo "You chose not to install, your system has not been modified." fi