diff --git a/src/install/default.txt b/src/install/default.txt index d32cb27..464f9ab 100644 --- a/src/install/default.txt +++ b/src/install/default.txt @@ -1,200 +1,670 @@ -#!/usr/bin/env bash +#!/bin/bash - +#=============================================================================== # -# Adapted from https://github.com/caddyserver/getcaddy.com +# FILE: default.txt +# +# USAGE: curl https://getcroc.schollz.com | bash +# OR +# wget -qO- https://getcroc.schollz.com | bash +# +# DESCRIPTION: croc Installer Script. # -# croc Installer Script +# This script installs croc into a specified prefix. +# Default prefix = /usr/local/bin # -# Homepage: https://schollz.com/software/croc -# Issues: https://github.com/schollz/croc/issues -# Requires: bash, mv, rm, tr, type, curl/wget, base64, sudo (if not root) -# tar (or unzip on OSX and Windows) +# OPTIONS: -p, --prefix "${INSTALL_PREFIX}" +# Prefix to install croc into. Defaults to /usr/local/bin +# REQUIREMENTS: bash, uname, tar/unzip, curl/wget, sudo (if not run +# as root), install, mktemp, sha256sum/shasum/sha256 # -# This script safely installs Caddy into your PATH (which may require -# password authorization). Use it like this: +# BUGS: ...hopefully not. Please report. # -# $ curl https://getcroc.schollz.com | bash -# or -# $ wget -qO- https://getcroc.schollz.com | bash -# -# In automated environments, you may want to run as root. -# If using curl, we recommend using the -fsSL flags. -# -# This should work on Mac, Linux, and BSD systems, and -# hopefully Windows with Cygwin. Please open an issue if -# you notice any bugs. +# NOTES: Homepage: https://schollz.com/software/croc +# Issues: https://github.com/schollz/croc/issues # +# CREATED: 08/10/2019 16:41 +# REVISION: 0.9.0 +#=============================================================================== +set -o nounset # Treat unset variables as an error -# [[ $- = *i* ]] && echo "Don't source this script!" && return 10 +#------------------------------------------------------------------------------- +# DEFAULTS +#------------------------------------------------------------------------------- +PREFIX="${PREFIX:-}" +ANDROID_ROOT="${ANDROID_ROOT:-}" -install_croc() -{ - trap 'echo -e "Aborted, error $? in command: $BASH_COMMAND"; trap ERR; exit 1' ERR - install_path="/usr/local/bin" - croc_os="unsupported" - croc_arch="unknown" - croc_arm="" - croc_version="6.1.3" +# Termux on Android has ${PREFIX} set which already ends with '/usr' +if [[ -n "${ANDROID_ROOT}" && -n "${PREFIX}" ]]; then + INSTALL_PREFIX="${PREFIX}/bin" +else + INSTALL_PREFIX="/usr/local/bin" +fi + +#------------------------------------------------------------------------------- +# FUNCTIONS +#------------------------------------------------------------------------------- - # Termux on Android has $PREFIX set which already ends with /usr - if [[ -n "$ANDROID_ROOT" && -n "$PREFIX" ]]; then - install_path="$PREFIX/bin" - fi +#--- FUNCTION ---------------------------------------------------------------- +# NAME: print_banner +# DESCRIPTION: Prints a banner +# PARAMETERS: none +# RETURNS: 0 +#------------------------------------------------------------------------------- +print_banner() { + cat <<-'EOF' +================================================= + ____ + / ___|_ __ ___ ___ + | | | '__/ _ \ / __| + | |___| | | (_) | (__ + \____|_| \___/ \___| - # Fall back to /usr/bin if necessary - if [[ ! -d $install_path ]]; then - install_path="/usr/bin" - fi - - # Not every platform has or needs sudo (https://termux.com/linux.html) - ((EUID)) && [[ -z "$ANDROID_ROOT" ]] && sudo_cmd="sudo" - - ######################### - # Which OS and version? # - ######################### - - croc_bin="croc" - croc_dl_ext=".tar.gz" - - # NOTE: `uname -m` is more accurate and universal than `arch` - # See https://en.wikipedia.org/wiki/Uname - unamem="$(uname -m)" - if [[ $unamem == *aarch64* ]]; then - croc_arch="ARM64" - elif [[ $unamem == *64* ]]; then - croc_arch="64bit" - elif [[ $unamem == *86* ]]; then - croc_arch="32bit" - elif [[ $unamem == *arm* ]]; then - croc_arch="ARM" - else - echo "Aborted, unsupported or unknown architecture: $unamem" - return 2 - fi - - unameu="$(tr '[:lower:]' '[:upper:]' <<<$(uname))" - if [[ $unameu == *DARWIN* ]]; then - croc_os="macOS" - vers=$(sw_vers) - version=${vers##*ProductVersion:} - IFS='.' read OSX_MAJOR OSX_MINOR _ <<<"$version" - - # # Major - # if ((OSX_MAJOR < 10)); then - # echo "Aborted, unsupported OS X version (9-)" - # return 3 - # fi - # if ((OSX_MAJOR > 10)); then - # echo "Aborted, unsupported OS X version (11+)" - # return 4 - # fi - - # # Minor - # if ((OSX_MINOR < 5)); then - # echo "Aborted, unsupported OS X version (10.5-)" - # return 5 - # fi - elif [[ $unameu == *LINUX* ]]; then - croc_os="Linux" - elif [[ $unameu == *FREEBSD* ]]; then - croc_os="FreeBSD" - elif [[ $unameu == *NETBSD* ]]; then - croc_os="NetBSD" - elif [[ $unameu == *OPENBSD* ]]; then - croc_os="OpenBSD" - elif [[ $unameu == *WIN* || $unameu == MSYS* ]]; then - # Should catch cygwin - sudo_cmd="" - croc_os="Windows" - croc_dl_ext=".zip" - croc_bin=$croc_bin.exe - else - echo "Aborted, unsupported or unknown os: $uname" - return 6 - fi - croc_file="croc_${croc_version}_${croc_os}-${croc_arch}${croc_dl_ext}" - - ######################## - # Download and extract # - ######################## - - croc_url="https://github.com/schollz/croc/releases/download/v${croc_version}/${croc_file}" - croc_checksum_url="https://github.com/schollz/croc/releases/download/v${croc_version}/croc_${croc_version}_checksums.txt" - echo "Downloading croc v${croc_version} (${croc_os} ${croc_arch})..." - - type -p gpg >/dev/null 2>&1 && gpg=1 || gpg=0 - - # Use $PREFIX for compatibility with Termux on Android - dl="$PREFIX$croc_file" - dl_checksum="$croc_file.checksum" - rm -rf -- "$dl" - rm -rf -- "$dl_checksum" - - - if type -p curl >/dev/null 2>&1; then - curl -fsSL "$croc_url" -o "$dl" - curl -fsSL "$croc_checksum_url" -o "$dl_checksum" - elif type -p wget >/dev/null 2>&1; then - wget --quiet "$croc_url" -O "$dl" - wget --quiet "$croc_checksum_url" -O "$dl_checksum" - else - echo "Aborted, could not find curl or wget" - return 7 - fi - - echo "Verifying checksum..." - if [[ $unameu == *DARWIN* ]]; then - checksum="$(shasum -a 256 ${dl})" - elif [[ $unameu == "FREEBSD" ]]; then - checksum="$(sha256 -q ${dl}) $croc_file" - else - checksum="$(sha256sum ${dl})" - fi - checksum_check="$(cat ${dl_checksum} | grep "${checksum}")" - - if [[ "${checksum}" != "${checksum_check}" ]]; then - echo "${checksum}" - echo "${checksum_check}" - echo "checksums are not valid, exiting" - return 7 - else - echo "verified checksum" - echo "Downloaded: ${checksum}" - echo "Remote: ${checksum_check}" - fi - - - echo "Extracting..." - case "$croc_file" in - *.zip) unzip -o "$dl" "$croc_bin" -d "$PREFIX/tmp/" ;; - *.tar.gz) tar -xzf "$dl" -C "$PREFIX/tmp/" "$croc_bin" ;; - esac - chmod +x "$PREFIX/tmp/$croc_bin" - - # Back up existing croc, if any found in path - if croc_path="$(type -p "$croc_bin")"; then - croc_backup="${croc_path}_old" - echo "Backing up $croc_path to $croc_backup" - echo "(Password may be required.)" - $sudo_cmd mv "$croc_path" "$croc_backup" - fi - - echo "Putting croc in $install_path (may require password)" - $sudo_cmd mv "$PREFIX/tmp/$croc_bin" "$install_path/$croc_bin" - if setcap_cmd=$(PATH+=$PATH:/sbin type -p setcap); then - $sudo_cmd $setcap_cmd cap_net_bind_service=+ep "$install_path/$croc_bin" - fi - $sudo_cmd rm -- "$dl" - $sudo_cmd rm -- "$dl_checksum" - - # check installation - $croc_bin -version - - echo "Successfully installed" - trap ERR - return 0 + ___ _ _ _ + |_ _|_ __ ___| |_ __ _| | | ___ _ __ + | || '_ \/ __| __/ _` | | |/ _ \ '__| + | || | | \__ \ || (_| | | | __/ | + |___|_| |_|___/\__\__,_|_|_|\___|_| +================================================== +EOF } -install_croc "$@" +#--- FUNCTION ---------------------------------------------------------------- +# NAME: print_help +# DESCRIPTION: Prints out a help message +# PARAMETERS: none +# RETURNS: 0 +#------------------------------------------------------------------------------- +print_help() { + local help_header + local help_message + + help_header="croc Installer Script" + help_message="Usage: + -p INSTALL_PREFIX + Prefix to install croc into. Directory must already exist. + Default = /usr/local/bin ('\${PREFIX}/bin' on Termux for Android) + + -h + Prints this helpfull message and exit." + + echo "${help_header}" + echo "" + echo "${help_message}" +} + +#--- FUNCTION ---------------------------------------------------------------- +# NAME: print_message +# DESCRIPTION: Prints a message all fancy like +# PARAMETERS: $1 = Message to print +# $2 = Severity. info, ok, error, warn +# RETURNS: Formatted Message to stdout +#------------------------------------------------------------------------------- +print_message() { + local message + local severity + local red + local green + local yellow + local nc + + message="${1}" + severity="${2}" + red='\e[0;31m' + green='\e[0;32m' + yellow='\e[1;33m' + nc='\e[0m' + + case "${severity}" in + "info" ) echo -e "${nc}${message}${nc}";; + "ok" ) echo -e "${green}${message}${nc}";; + "error" ) echo -e "${red}${message}${nc}";; + "warn" ) echo -e "${yellow}${message}${nc}";; + esac +} + +#--- FUNCTION ---------------------------------------------------------------- +# NAME: make_tempdir +# DESCRIPTION: Makes a temp dir using mktemp if available +# PARAMETERS: $1 = Directory template +# RETURNS: 0 = Created temp dir. Also prints temp file path to stdout +# 1 = Failed to create temp dir +# 20 = Failed to find mktemp +#------------------------------------------------------------------------------- +make_tempdir() { + local template + local tempdir + local tempdir_rcode + + template="${1}.XXXXXX" + + if command -v mktemp >/dev/null 2>&1; then + tempdir="$(mktemp -d -t "${template}")" + tempdir_rcode="${?}" + if [[ "${tempdir_rcode}" == "0" ]]; then + echo "${tempdir}" + return 0 + else + return 1 + fi + else + return 20 + fi +} + +#--- FUNCTION ---------------------------------------------------------------- +# NAME: determine_os +# DESCRIPTION: Attempts to determin host os using uname +# PARAMETERS: none +# RETURNS: 0 = OS Detected. Also prints detected os to stdout +# 1 = Unkown OS +# 20 = 'uname' not found in path +#------------------------------------------------------------------------------- +determine_os() { + local uname_out + + if command -v uname >/dev/null 2>&1; then + uname_out="$(uname)" + if [[ "${uname_out}" == "" ]]; then + return 1 + else + echo "${uname_out}" + return 0 + fi + else + return 20 + fi +} + +#--- FUNCTION ---------------------------------------------------------------- +# NAME: determine_arch +# DESCRIPTION: Attempt to determin architecture of host +# PARAMETERS: none +# RETURNS: 0 = Arch Detected. Also prints detected arch to stdout +# 1 = Unkown arch +# 20 = 'uname' not found in path +#------------------------------------------------------------------------------- +determine_arch() { + local uname_out + + if command -v uname >/dev/null 2>&1; then + uname_out="$(uname -m)" + if [[ "${uname_out}" == "" ]]; then + return 1 + else + echo "${uname_out}" + return 0 + fi + else + return 20 + fi +} + + +#--- FUNCTION ---------------------------------------------------------------- +# NAME: download_file +# DESCRIPTION: Downloads a file into the specified directory. Attempts to +# use curl, then wget. If neither is found, fail. +# PARAMETERS: $1 = url of file to download +# $2 = location to download file into on host system +# RETURNS: If curl or wget found, returns the return code of curl or wget +# 20 = Could not find curl and wget +#------------------------------------------------------------------------------- +download_file() { + local url + local dir + local filename + local rcode + + url="${1}" + dir="${2}" + filename="${3}" + + if command -v curl >/dev/null 2>&1; then + curl -fsSL "${url}" -o "${dir}/${filename}" + rcode="${?}" + elif command -v wget >/dev/null 2>&1; then + wget --quiet "${url}" -O "${dir}/${filename}" + rcode="${?}" + else + rcode="20" + fi + + return "${rcode}" +} + +#--- FUNCTION ---------------------------------------------------------------- +# NAME: checksum_check +# DESCRIPTION: Attempt to verify checksum of downloaded file to ensure +# integrity. Tries multiple tools before faling. +# PARAMETERS: $1 = path to checksum file +# $2 = location of file to check +# $3 = working directory +# RETURNS: 0 = checkusm verified +# 1 = checksum verification failed +# 20 = failed to determine tool to use to check checksum +# 30 = failed to change into or go back from working dir +#------------------------------------------------------------------------------- +checksum_check() { + local checksum_file + local file + local dir + local rcode + local shasum_1 + local shasum_2 + local shasum_c + + checksum_file="${1}" + file="${2}" + dir="${3}" + + cd "${dir}" || return 30 + if command -v sha256sum >/dev/null 2>&1; then + ## Not all sha256sum versions seem to have --ignore-missing, so filter the checksum file + ## to only include the file we downloaded. + grep "$(basename "${file}")" "${checksum_file}" > filtered_checksum.txt + shasum_c="$(sha256sum -c "filtered_checksum.txt")" + rcode="${?}" + elif command -v shasum >/dev/null 2>&1; then + ## With shasum on FreeBSD, we don't get to --ignore-missing, so filter the checksum file + ## to only include the file we downloaded. + grep "$(basename "${file}")" "${checksum_file}" > filtered_checksum.txt + shasum_c="$(shasum -a 256 -c "filtered_checksum.txt")" + rcode="${?}" + elif command -v sha256 >/dev/null 2>&1; then + ## With sha256 on FreeBSD, we don't get to --ignore-missing, so filter the checksum file + ## to only include the file we downloaded. + ## Also sha256 -c option seems to fail, so fall back to an if statement + grep "$(basename "${file}")" "${checksum_file}" > filtered_checksum.txt + shasum_1="$(sha256 -q "${file}")" + shasum_2="$(awk '{print $1}' filtered_checksum.txt)" + if [[ "${shasum_1}" == "${shasum_2}" ]]; then + rcode="0" + else + rcode="1" + fi + shasum_c="Expected: ${shasum_1}, Got: ${shasum_2}" + else + return 20 + fi + cd - >/dev/null 2>&1 || return 30 + + if [[ "${rcode}" -gt "0" ]]; then + echo "${shasum_c}" + fi + return "${rcode}" +} + +#--- FUNCTION ---------------------------------------------------------------- +# NAME: extract_file +# DESCRIPTION: Extracts a file into a location. Attempts to determine which +# tool to use by checking file extention. +# PARAMETERS: $1 = file to extract +# $2 = location to extract file into +# $3 = extention +# RETURNS: Return code of the tool used to extract the file +# 20 = Failed to determine which tool to use +# 30 = Failed to find tool in path +#------------------------------------------------------------------------------- +extract_file() { + local file + local dir + local ext + local rcode + + file="${1}" + dir="${2}" + ext="${3}" + + case "${ext}" in + "zip" ) if command -v unzip >/dev/null 2>&1; then + unzip "${file}" -d "${dir}" + rcode="${?}" + else + rcode="30" + fi + ;; + "tar.gz" ) if command -v tar >/dev/null 2>&1; then + tar -xf "${file}" -C "${dir}" + rcode="${?}" + else + rcode="30" + fi + ;; + * ) rcode="20";; + esac + + return "${rcode}" +} + +#--- FUNCTION ---------------------------------------------------------------- +# NAME: install_file_freebsd +# DESCRIPTION: Installs a file into a location using 'install'. If EUID not +# 0, then attempt to use sudo. +# PARAMETERS: $1 = file to install +# $2 = location to install file into +# RETURNS: 0 = File Installed +# 1 = File not installed +# 20 = Could not find install command +# 21 = Could not find sudo command +#------------------------------------------------------------------------------- +install_file_freebsd() { + local file + local prefix + local rcode + + file="${1}" + prefix="${2}" + + if command -v install >/dev/null 2>&1; then + if [[ "${EUID}" == "0" ]]; then + install -C -b -B '_old' -m 755 "${file}" "${prefix}" + rcode="${?}" + else + if command -v sudo >/dev/null 2>&1; then + sudo install -C -b -B '_old' -m 755 "${file}" "${prefix}" + rcode="${?}" + else + rcode="21" + fi + fi + else + rcode="20" + fi + + return "${rcode}" +} + + +#--- FUNCTION ---------------------------------------------------------------- +# NAME: install_file_linux +# DESCRIPTION: Installs a file into a location using 'install'. If EUID not +# 0, then attempt to use sudo (unless on android). +# PARAMETERS: $1 = file to install +# $2 = location to install file into +# RETURNS: 0 = File Installed +# 1 = File not installed +# 20 = Could not find install command +# 21 = Could not find sudo command +#------------------------------------------------------------------------------- +install_file_linux() { + local file + local prefix + local rcode + + file="${1}" + prefix="${2}" + + if command -v install >/dev/null 2>&1; then + if [[ "${EUID}" == "0" ]]; then + install -C -b -S '_old' -m 755 -t "${prefix}" "${file}" + rcode="${?}" + else + if command -v sudo >/dev/null 2>&1; then + sudo install -C -b -S '_old' -m 755 "${file}" "${prefix}" + rcode="${?}" + elif [[ "${ANDROID_ROOT}" != "" ]]; then + install -C -b -S '_old' -m 755 -t "${prefix}" "${file}" + rcode="${?}" + else + rcode="21" + fi + fi + else + rcode="20" + fi + + return "${rcode}" +} + +#--- FUNCTION ---------------------------------------------------------------- +# NAME: install_file_cygwin +# DESCRIPTION: Installs a file into a location using 'install'. If EUID not +# 0, then attempt to use sudo. +# Not really 100% sure this is how to install croc in cygwin. +# PARAMETERS: $1 = file to install +# $2 = location to install file into +# RETURNS: 0 = File Installed +# 20 = Could not find install command +# 21 = Could not find sudo command +#------------------------------------------------------------------------------- +install_file_cygwin() { + local file + local prefix + local rcode + + file="${1}" + prefix="${2}" + + if command -v install >/dev/null 2>&1; then + if [[ "${EUID}" == "0" ]]; then + install -m 755 "${prefix}" "${file}" + rcode="${?}" + else + if command -v sudo >/dev/null 2>&1; then + sudo install -m 755 "${file}" "${prefix}" + rcode="${?}" + else + rcode="21" + fi + fi + else + rcode="20" + fi + + return "${rcode}" +} + +#--- FUNCTION ---------------------------------------------------------------- +# NAME: main +# DESCRIPTION: Put it all together in a logical way +# ...at least that is the hope... +# PARAMETERS: 1 = prefix +# RETURNS: 0 = All good +# 1 = Something done broke +#------------------------------------------------------------------------------- +main() { + local prefix + local tmpdir + local tmpdir_rcode + local croc_arch + local croc_arch_rcode + local croc_os + local croc_os_rcode + local croc_base_url + local croc_url + local croc_file + local croc_checksum_file + local croc_bin_name + local croc_version + local croc_dl_ext + local download_file_rcode + local download_checksum_file_rcode + local checksum_check_rcode + local extract_file_rcode + local install_file_rcode + + croc_bin_name="croc" + croc_version="6.1.3" + croc_dl_ext="tar.gz" + croc_base_url="https://github.com/schollz/croc/releases/download" + prefix="${1}" + + print_banner + print_message "== Install prefix set to ${prefix}" "info" + + tmpdir="$(make_tempdir "${croc_bin_name}")" + tmpdir_rcode="${?}" + if [[ "${tmpdir_rcode}" == "0" ]]; then + print_message "== Created temp dir at ${tmpdir}" "info" + elif [[ "${tmpdir_rcode}" == "1" ]]; then + print_message "== Failed to create temp dir at ${tmpdir}" "error" + else + print_message "== 'mktemp' not found in path. Is it installed?" "error" + exit 1 + fi + + croc_arch="$(determine_arch)" + croc_arch_rcode="${?}" + if [[ "${croc_arch_rcode}" == "0" ]]; then + print_message "== Architecture detected as ${croc_arch}" "info" + elif [[ "${croc_arch_rcode}" == "1" ]]; then + print_message "== Architecture not detected" "error" + exit 1 + else + print_message "== 'uname' not found in path. Is it installed?" "error" + exit 1 + fi + + croc_os="$(determine_os)" + croc_os_rcode="${?}" + if [[ "${croc_os_rcode}" == "0" ]]; then + print_message "== OS detected as ${croc_os}" "info" + elif [[ "${croc_os_rcode}" == "1" ]]; then + print_message "== OS not detected" "error" + exit 1 + else + print_message "== 'uname' not found in path. Is it installed?" "error" + exit 1 + fi + + case "${croc_os}" in + "Darwin" ) croc_os="macOS";; + "CYGWIN"* ) croc_os="Windows"; + croc_dl_ext="zip"; + print_message "== Cygwin is currently unsupported." "error"; + exit 1;; + esac + + case "${croc_arch}" in + "x86_64" ) croc_arch="64bit";; + "amd64" ) croc_arch="64bit";; + "aarch64" ) croc_arch="ARM64";; + "armv7l" ) croc_arch="ARM";; + "i686" ) croc_arch="32bit";; + * ) croc_arch="unknown";; + esac + + croc_file="${croc_bin_name}_${croc_version}_${croc_os}-${croc_arch}.${croc_dl_ext}" + croc_checksum_file="${croc_bin_name}_${croc_version}_checksums.txt" + croc_url="${croc_base_url}/v${croc_version}/${croc_file}" + croc_checksum_url="${croc_base_url}/v${croc_version}/${croc_checksum_file}" + + download_file "${croc_url}" "${tmpdir}" "${croc_file}" + download_file_rcode="${?}" + if [[ "${download_file_rcode}" == "0" ]]; then + print_message "== Downloaded croc archive into ${tmpdir}" "info" + elif [[ "${download_file_rcode}" == "1" ]]; then + print_message "== Failed to download croc archive" "error" + exit 1 + elif [[ "${download_file_rcode}" == "20" ]]; then + print_message "== Failed to locate curl or wget" "error" + exit 1 + else + print_message "== Return code of download tool returned an unexpected value of ${download_file_rcode}" "error" + exit 1 + fi + download_file "${croc_checksum_url}" "${tmpdir}" "${croc_checksum_file}" + download_checksum_file_rcode="${?}" + if [[ "${download_checksum_file_rcode}" == "0" ]]; then + print_message "== Downloaded croc checksums file into ${tmpdir}" "info" + elif [[ "${download_checksum_file_rcode}" == "1" ]]; then + print_message "== Failed to download croc checksums" "error" + exit 1 + elif [[ "${download_checksum_file_rcode}" == "20" ]]; then + print_message "== Failed to locate curl or wget" "error" + exit 1 + else + print_message "== Return code of download tool returned an unexpected value of ${download_checksum_file_rcode}" "error" + exit 1 + fi + + checksum_check "${tmpdir}/${croc_checksum_file}" "${tmpdir}/${croc_file}" "${tmpdir}" + checksum_check_rcode="${?}" + if [[ "${checksum_check_rcode}" == "0" ]]; then + print_message "== Checksum of ${tmpdir}/${croc_file} verified" "ok" + elif [[ "${checksum_check_rcode}" == "1" ]]; then + print_message "== Failed to verify checksum of ${tmpdir}/${croc_file}" "error" + exit 1 + elif [[ "${checksum_check_rcode}" == "20" ]]; then + print_message "== Failed to find tool to verify sha256 sums" "error" + exit 1 + elif [[ "${checksum_check_rcode}" == "30" ]]; then + print_message "== Failed to change into working directory ${tmpdir}" "error" + exit 1 + else + print_message "== Unknown return code returned while checking checksum of ${tmpdir}/${croc_file}. Returned ${checksum_check_rcode}" "error" + exit 1 + fi + + extract_file "${tmpdir}/${croc_file}" "${tmpdir}/" "${croc_dl_ext}" + extract_file_rcode="${?}" + if [[ "${extract_file_rcode}" == "0" ]]; then + print_message "== Extracted ${croc_file} to ${tmpdir}/" "info" + elif [[ "${extract_file_rcode}" == "1" ]]; then + print_message "== Failed to extract ${croc_file}" "error" + exit 1 + elif [[ "${extract_file_rcode}" == "20" ]]; then + print_message "== Failed to determine which extraction tool to use" "error" + exit 1 + elif [[ "${extract_file_rcode}" == "30" ]]; then + print_message "== Failed to find extraction tool in path" "error" + exit 1 + else + print_message "== Unknown error returned from extraction attempt" "error" + exit 1 + fi + + case "${croc_os}" in + "Linux" ) install_file_linux "${tmpdir}/${croc_bin_name}" "${prefix}/"; + install_file_rcode="${?}";; + "FreeBSD" ) install_file_freebsd "${tmpdir}/${croc_bin_name}" "${prefix}/"; + install_file_rcode="${?}";; + "macOS" ) install_file_freebsd "${tmpdir}/${croc_bin_name}" "${prefix}/"; + install_file_rcode="${?}";; + "Windows" ) install_file_cygwin "${tmpdir}/${croc_bin_name}" "${prefix}/"; + install_file_rcode="${?}";; + esac + if [[ "${install_file_rcode}" == "0" ]]; then + print_message "== Installed ${croc_bin_name} to ${prefix}/" "ok" + elif [[ "${install_file_rcode}" == "1" ]]; then + print_message "== Failed to install ${croc_bin_name}" "error" + exit 1 + elif [[ "${install_file_rcode}" == "20" ]]; then + print_message "== Failed to locate 'install' command" "error" + exit 1 + elif [[ "${install_file_rcode}" == "21" ]]; then + print_message "== Failed to locate 'sudo' command" "error" + exit 1 + else + print_message "== Install attempt returned an unexpected value of ${install_file_rcode}" "error" + exit 1 + fi + + print_message "== Installation complete" "ok" + + exit 0 +} + +#------------------------------------------------------------------------------- +# ARGUMENT PARSING +#------------------------------------------------------------------------------- +OPTS="hp:" +while getopts "${OPTS}" optchar; do + case "${optchar}" in + 'h' ) print_help + exit 0 + ;; + 'p' ) INSTALL_PREFIX="${OPTARG}" + ;; + /? ) print_message "Unknown option ${OPTARG}" "warn" + ;; + esac +done + +#------------------------------------------------------------------------------- +# CALL MAIN +#------------------------------------------------------------------------------- +main "${INSTALL_PREFIX}"