From 5f2db41d3a6d05cc6dd12350069472ae33d8869a Mon Sep 17 00:00:00 2001 From: Christopher Beckmann Date: Tue, 23 May 2023 23:53:27 +0200 Subject: [PATCH] Added zoxide and added more robust arch detection --- kfg | 630 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 542 insertions(+), 88 deletions(-) diff --git a/kfg b/kfg index 1a621a7..f413d15 100644 --- a/kfg +++ b/kfg @@ -1,10 +1,10 @@ #!/bin/bash NAME="kfg" -VERSION="0.3" +VERSION="0.4" HOME_PATH="$HOME" -TMP_PATH="$HOME_PATH/tmp/kamu_install" +TMP_PATH="$HOME_PATH/.tmp/kfg_install" CONFIG_PATH="$HOME_PATH/.config" BINARY_PATH="/usr/bin" RC_FILE=".zshrc" @@ -24,6 +24,7 @@ TOOLS[unp]="Perl script to make file archive extraction easier" TOOLS[bat]="cat replacement with syntax highlighting and git integration - https://github.com/sharkdp/bat" TOOLS[lsd]="ls replacement with colors, icons, tree-view and more - https://github.com/lsd-rs/lsd" TOOLS[omp]="Customisable shell prompt renderer - https://github.com/jandedobbeleer/oh-my-pos" +TOOLS[zoxide]="A smarter cd command. - https://github.com/ajeetdsouza/zoxide" function show_help_name { echo "$NAME v$VERSION" @@ -72,7 +73,12 @@ function log_info { } function log_error { - log $ERROR "!" "$1" + echo "$(log $ERROR "!" "$1")" >&2 +} + +function err { + log_error "Error: $1" + exit 1 } function log_debug { @@ -118,7 +124,8 @@ function download_config { FILE="$CONFIG_PATH/$1/$2" if [ ! -e "$FILE" ] || user_confirm_overwrite "$FILE"; then - wget -O "$FILE" "$3" > /dev/null 2>&1 + download "$3" "$FILE" + #wget -O "$FILE" "$3" > /dev/null 2>&1 log_add "Added $FILE" fi } @@ -134,7 +141,8 @@ function install_rc { # Does the file already exist? or does the user want to overwrite it? if [ ! -e "$FILE" ] || user_confirm_overwrite "$FILE"; then # Download the file and save it - wget -O "$FILE" "$2" > /dev/null 2>&1 + download "$2" "$FILE" + #wget -O "$FILE" "$2" > /dev/null 2>&1 log_add "Added $FILE" fi @@ -180,11 +188,156 @@ function init_install_rc { fi } +function download { + local _url=$1 + local _path=$2 + local _result + + if check_cmd curl; then + _dld=curl + elif check_cmd wget; then + _dld=wget + else + need_cmd 'curl or wget' + fi + + if [ ! -z $_path ]; then + + mkdir -p "$(dirname "$_path")" + log_info "Downloading $_url to $_path" + + case "${_dld}" in + curl) _args="-sLo $_path" ;; + wget) _args="-qO $_path" ;; + esac + + else + + case "${_dld}" in + curl) _args="-sL" ;; + wget) _args="-qO-" ;; + esac + + fi + + case "${_dld}" in + curl) _result="$(curl $_args "${_url}")" || err "curl: failed to download ${_url}" ;; + wget) _result="$(wget $_args "${_url}")" || err "wget: failed to download ${_url}" ;; + *) err "unsupported downloader: ${_dld}" ;; + esac + + RETVAL="${_result}" + return 0 +} + +function github_install { + ensure get_architecture + + local _program=$1 + local _arch="${RETVAL}" + local _url="https://api.github.com/repos/$2/releases/latest" + + assert_nz "${_arch}" "arch" + + need_cmd grep + + download "${_url}" + local _releases=$RETVAL + + (echo "${_releases}" | grep -q 'API rate limit exceeded') && (log_error "GitHub API rate limit exceeded. Please try again later." || return 1) + + local _package_url _package_urls + _package_urls="$(echo "${_releases}" | grep "browser_download_url" | cut -d '"' -f 4)" + + #log_debug "Packages: ${_package_urls}" + + # Check for Rust package + local _rust_package_url="$(echo "$_package_urls" | grep $_arch)" + local _other_package_url="$(echo "$_package_urls" | grep $ARCH | grep -vE "$APP_FILTER")" + + log_debug "Rust package: $_rust_package_url" + log_debug "Filter: $APP_FILTER" + log_debug "Other package: $_other_package_url" + + if [ ! -z "$_other_package_url" ]; then + _package_url="${_other_package_url}" + elif [ ! -z "$_rust_package_url" ]; then + _package_url="${_rust_package_url}" + else + log_error "Can not find installable package for '$_program' for the detected architecture (${_arch})." + return 0 + fi + + log_debug "Selected package: ${_package_url}" + + # Check the extension + local _ext + case "${_package_url}" in + *.tar.gz) _ext="tar.gz" ;; + *.deb) _ext="deb" ;; + *.zip) _ext="zip" ;; + *) _ext="" ;; + esac + + local _package + if [ -z $_ext ]; then + _package="$TMP_PATH/$_program" + else + _package="$TMP_PATH/$_program.$_ext" + fi + + download "$_package_url" "$_package" + + # unpack + cd "${TMP_PATH}" + case "${_package}" in + *.tar.gz) + need_cmd tar + log_info "Unpacking ${_package}" + tar -xf "${_package}" + ;; + *.zip) + need_cmd unzip + log_info "Unpacking ${_package}" + unzip -oq "${_package}" + ;; + *) ;; # ignore + esac + + # install + local _binary + case "${_ext}" in + tar.gz) + _binary="$(tar --list -f "${_package}" | grep -E "^(.*/)?$_program$")" + log_debug $_binary + install_binary "$_program" "$TMP_PATH/$_binary" + return 0 + ;; + deb) + install_deb "${_program}" "${_package}" + return 0 + ;; + zip) + _binary="$(unzip -l "${_package}" | sed -E 's/ {1,}/ /g' | cut -d ' ' -f 5 | grep -E "^(.*/)?$_program$")" + log_debug $_binary + install_binary "$_program" "$TMP_PATH/$_binary" + return 0 + ;; + *) + _binary="${_program}" + log_debug $_binary + log_debug "Installing binary!" + install_binary "$_program" "$TMP_PATH/$_binary" + ;; + esac + +} + function install_deb_check { CHECK_CURRENT=$(dpkg -s "$1" | grep -E "Status|Version") INSTALLED_CURRENT=$(echo $CHECK_CURRENT | grep -oE "Status: .*" | cut -d ' ' -f 2) VERSION_CURRENT=$(echo $CHECK_CURRENT | grep -oE "Version: .*" | cut -d ' ' -f 2) - CHECK_NEW=$(sudo dpkg -I $TMP_PATH/$1.deb | grep -E "Status|Version") + CHECK_NEW=$(sudo dpkg -I $2 | grep -E "Status|Version") INSTALLED_NEW=$(echo $CHECK_NEW | grep -oE "Status: .*" | cut -d ' ' -f 2) VERSION_NEW=$(echo $CHECK_NEW | grep -oE "Version: .*" | cut -d ' ' -f 2) @@ -203,15 +356,17 @@ function install_deb_check { } function install_deb { - if [ -z "$P_DEB" ]; then return 0; fi - log_info "Downloading $2 to $TMP_PATH ..." - wget -O $TMP_PATH/$1.deb $2 > /dev/null 2>&1 + local _file=$2 + local _program=$1 + #if [ -z "$P_DEB" ]; then return 0; fi + #log_info "Downloading $2 to $TMP_PATH ..." + #wget -O $TMP_PATH/$1.deb $2 > /dev/null 2>&1 - if ! install_deb_check $1; then + if ! install_deb_check "$_program" "$_file"; then return 1 fi - INSTALL=$(sudo dpkg -i $TMP_PATH/$1.deb) + INSTALL=$(sudo dpkg -i $_file) UNPACK=$(echo -n "$INSTALL" | grep -oE "Unpacking .*") PROG=$(echo -n $UNPACK | cut -d '(' -f 1 | cut -d ' ' -f 2) CURR_VERSION=$(echo -n $UNPACK | cut -d '(' -f 2 | cut -d ')' -f 1) @@ -228,13 +383,13 @@ function install_deb { } function init { - if [ ! -z "$P_BINARY" ] || [ ! -z "$P_DEB" ]; then - log_info "Found Architecture: $ARCH" - if ! user_confirm "Is '$ARCH' the correct architecture to download programs?"; then - log_info "Exiting ..." - exit 0 - fi - fi + #if [ ! -z "$P_BINARY" ] || [ ! -z "$P_DEB" ]; then + # log_info "Found Architecture: $ARCH" + # if ! user_confirm "Is '$ARCH' the correct architecture to download programs?"; then + # log_info "Exiting ..." + # exit 0 + # fi + #fi if [ ! -z "$P_APT" ]; then log_info "Running apt update ..." sudo apt update > /dev/null 2>&1 @@ -257,23 +412,23 @@ function apt_install { fi } -function github_latest { - VERSION=$(curl -I "https://github.com/$1/releases/latest/" 2> /dev/null | grep -iE "^Location:" | tr -s ' ' | cut -d '/' -f 8 2> /dev/null) - echo -n ${VERSION//[$'\t\r\n']} -} +#function github_latest { +# VERSION=$(curl -I "https://github.com/$1/releases/latest/" 2> /dev/null | grep -iE "^Location:" | tr -s ' ' | cut -d '/' -f 8 2> /dev/null) +# echo -n ${VERSION//[$'\t\r\n']} +#} -function install_deb_github { - if [ -z "$P_DEB" ]; then return 0; fi - local PATTERN=${3/ARCH/$ARCH}; - log_debug "Loading most recent version for $1" - local VERSION=$(github_latest $2 2> /dev/null ) - VERSION=${VERSION/v/} - log_debug "Found version $VERSION" - local FILE=${PATTERN/VERSION/$VERSION} - local LINK="https://github.com/$2/releases/latest/download/$FILE" - log_debug "Download link: $LINK" - install_deb "$1" ${LINK//[$'\t\r\n']} -} +#function install_deb_github { +# if [ -z "$P_DEB" ]; then return 0; fi +# local PATTERN=${3/ARCH/$ARCH}; +# log_debug "Loading most recent version for $1" +# local VERSION=$(github_latest $2 2> /dev/null ) +# VERSION=${VERSION/v/} +# log_debug "Found version $VERSION" +# local FILE=${PATTERN/VERSION/$VERSION} +# local LINK="https://github.com/$2/releases/latest/download/$FILE" +# log_debug "Download link: $LINK" +# install_deb "$1" ${LINK//[$'\t\r\n']} +#} function git_clone { CLONE=$(git clone "$1" "$2" 2>&1) @@ -285,24 +440,30 @@ function git_clone { } function install_binary { + local _app=$1 + local _path=$2 if [ -z "$P_BINARY" ]; then return 0; fi - log_info "Downloading $2 to $BINARY_PATH ..." - sudo wget -O $BINARY_PATH/$1 $2 > /dev/null 2>&1 - sudo chmod +x $BINARY_PATH/$1 + #log_info "Downloading $2 to $BINARY_PATH ..." + #sudo wget -O $BINARY_PATH/$1 $2 > /dev/null 2>&1 + log_debug $_path + log_debug $BINARY_PATH/$_app + sudo cp $_path $BINARY_PATH/$_app + sudo chmod +x $BINARY_PATH/$_app + log_add "Installed $_app into $BINARY_PATH/$_app" } -function install_binary_github { - if [ -z "$P_BINARY" ]; then return 0; fi - local PATTERN=${3/ARCH/$ARCH}; - log_debug "Loading most recent version for $1" - VERSION=$(github_latest $2 2> /dev/null) - VERSION=${VERSION/v/} - log_debug "Found version $VERSION" - local FILE=${PATTERN/VERSION/$VERSION} - local LINK="https://github.com/$2/releases/latest/download/$FILE" - log_debug "Download link: $LINK" - install_binary "$1" ${LINK//[$'\t\r\n']} -} +#function install_binary_github { +# if [ -z "$P_BINARY" ]; then return 0; fi +# local PATTERN=${3/ARCH/$ARCH}; +# log_debug "Loading most recent version for $1" +# VERSION=$(github_latest $2 2> /dev/null) +# VERSION=${VERSION/v/} +# log_debug "Found version $VERSION" +# local FILE=${PATTERN/VERSION/$VERSION} +# local LINK="https://github.com/$2/releases/latest/download/$FILE" +# log_debug "Download link: $LINK" +# install_binary "$1" ${LINK//[$'\t\r\n']} +#} function set_shell { if [ -z "$P_ZSH" ]; then return 0; fi @@ -321,7 +482,7 @@ function set_shell { function update { cd "$(dirname "$0")" - wget -O kfg https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/kfg + download "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/kfg" "kfg" exit 0 } @@ -329,8 +490,19 @@ function show_help_install { show_help_name echo -e "Usage: $NAME install [ opt ]\n" echo -e "program := {" + local _length _space for key in ${!TOOLS[@]}; do - echo -e " ${INFO}${key}${ENDCOLOR}\t\t\t ${TOOLS[$key]}" + _length="$(echo -n $key | wc -m)" + if [ "$_length" -gt 21 ]; then + _space="" + elif [ "$_length" -gt 13 ]; then + _space="\t" + elif [ "$_length" -gt 5 ]; then + _space="\t\t" + else + _space="\t\t\t" + fi + echo -e " ${INFO}${key}${ENDCOLOR}${_space} ${TOOLS[$key]}" done echo -e "}\n" show_help_opt @@ -344,6 +516,7 @@ function p_all { p_bat p_lsd p_omp + p_zoxide } function p_zsh { @@ -385,7 +558,8 @@ function p_bat { # ----------------- # bat # ----------------- - install_deb_github bat "sharkdp/bat" "bat_VERSION_ARCH.deb" + github_install bat "sharkdp/bat" + #install_deb_github bat "sharkdp/bat" "bat_VERSION_ARCH.deb" install_rc bat https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.bat.rc } @@ -393,24 +567,31 @@ function p_lsd { # ----------------- # Install lsd https://github.com/Peltoche/lsd # ----------------- - install_deb_github "lsd" "lsd-rs/lsd" "lsd_VERSION_ARCH.deb" + github_install "lsd" "lsd-rs/lsd" + #install_deb_github "lsd" "lsd-rs/lsd" "lsd_VERSION_ARCH.deb" install_rc lsd https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.lsd.rc download_config lsd "config.yaml" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.lsd.conf" download_config lsd "themes/kamu.yaml" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.lsd.theme" } +function p_zoxide { + github_install "zoxide" "ajeetdsouza/zoxide" +} + function p_omp { # ----------------- # Install OhMyPosh # ----------------- + github_install "oh-my-posh" "JanDeDobbeleer/oh-my-posh" download_config "omp" "omp.json" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.omp.json" install_rc "omp" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.omp.rc" - install_binary_github "oh-my-posh" "JanDeDobbeleer/oh-my-posh" "posh-linux-ARCH" + #install_binary_github "oh-my-posh" "JanDeDobbeleer/oh-my-posh" "posh-linux-ARCH" } function install { if [ -z $1 ]; then show_help_install + exit 0 fi init @@ -436,57 +617,330 @@ function install { unp) p_unp; shift ;; lsd) p_lsd; shift ;; omp) p_omp; shift ;; + zoxide) p_zoxide; shift ;; # If invalid options were passed, then getopt should have reported an error, # which we checked as VALID_ARGUMENTS when getopt was called... *) log_error "Unrecognised program: $1"; shift ;; esac done - cleanup + #cleanup exit 0 } -if [ -z $1 ]; then - show_help -fi +function main { + if [ -z $1 ]; then + show_help + fi -PARSED_ARGUMENTS=$(getopt -a -n install.sh -o hvdya: --long yes,help,debug,arch,verbose: -- "$@") -VALID_ARGUMENTS=$? -if [ "$VALID_ARGUMENTS" != "0" ]; then - show_help -fi + PARSED_ARGUMENTS=$(getopt -a -n install.sh -o hvdya: --long yes,help,debug,arch,verbose: -- "$@") + VALID_ARGUMENTS=$? + if [ "$VALID_ARGUMENTS" != "0" ]; then + show_help + fi -ARCH=$(/usr/bin/dpkg --print-architecture) + ARCH=$(/usr/bin/dpkg --print-architecture) -#echo "PARSED_ARGUMENTS is $PARSED_ARGUMENTS" -eval set -- "$PARSED_ARGUMENTS" -while : -do + #echo "PARSED_ARGUMENTS is $PARSED_ARGUMENTS" + eval set -- "$PARSED_ARGUMENTS" + while : + do + case "$1" in + -h | --help) show_help ;; + -v | --verbose) P_Verbose=1 ; shift ;; + -d | --debug) P_Debug=1 ; shift ;; + -y | --yes) P_Yes=1 ; shift ;; + -a | --arch) ARCH="$2" ; shift 2 ;; + # -- means the end of the arguments; drop this, and break out of the while loop + --) shift; break ;; + # If invalid options were passed, then getopt should have reported an error, + # which we checked as VALID_ARGUMENTS when getopt was called... + *) log_error "Unexpected option: $1" + show_help ;; + esac + done + + #echo "Parameters remaining are: $@" case "$1" in - -h | --help) show_help ;; - -v | --verbose) P_Verbose=1 ; shift ;; - -d | --debug) P_Debug=1 ; shift ;; - -y | --yes) P_Yes=1 ; shift ;; - -a | --arch) ARCH="$2" ; shift 2 ;; + update) update ;; + version) version ;; + install) shift; install $@;; # -- means the end of the arguments; drop this, and break out of the while loop --) shift; break ;; # If invalid options were passed, then getopt should have reported an error, # which we checked as VALID_ARGUMENTS when getopt was called... - *) log_error "Unexpected option: $1" - show_help ;; + *) log_error "Unexpected command: $1"; show_help ;; esac -done +} -#echo "Parameters remaining are: $@" -case "$1" in - update) update ;; - version) version ;; - install) shift; install $@;; - # -- means the end of the arguments; drop this, and break out of the while loop - --) shift; break ;; - # If invalid options were passed, then getopt should have reported an error, - # which we checked as VALID_ARGUMENTS when getopt was called... - *) log_error "Unexpected command: $1" - show_help ;; -esac +# The following is from (with modifications): https://github.com/rust-lang/rustup/blob/4c1289b2c3f3702783900934a38d7c5f912af787/rustup-init.sh +function get_architecture { + _ostype="$(uname -s)" + _cputype="$(uname -m)" + _clibtype="gnu" + + APP_FILTER="arm64|amd64|aarch64|i686|x86_64|x86-64|x64|musl|gnu|windows|darwin|linux|android|exe|sig|sha256" + + if [ "${_ostype}" = Linux ]; then + if [ "$(uname -o || true)" = Android ]; then + _ostype=Android + fi + + if ldd --version 2>&1 | grep -q 'musl'; then + _clibtype="musl" + APP_FILTER=$(echo $APP_FILTER | sed -e "s/musl|//gi") + else + APP_FILTER=$(echo $APP_FILTER | sed -e "s/gnu|//gi") + fi + fi + + if [ "${_ostype}" = Darwin ] && [ "${_cputype}" = i386 ]; then + # Darwin `uname -m` lies + if sysctl hw.optional.x86_64 | grep -q ': 1'; then + _cputype=x86_64 + fi + fi + + if [ "${_ostype}" = SunOS ]; then + # Both Solaris and illumos presently announce as "SunOS" in "uname -s" + # so use "uname -o" to disambiguate. We use the full path to the + # system uname in case the user has coreutils uname first in PATH, + # which has historically sometimes printed the wrong value here. + if [ "$(/usr/bin/uname -o || true)" = illumos ]; then + _ostype=illumos + fi + + # illumos systems have multi-arch userlands, and "uname -m" reports the + # machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86 + # systems. Check for the native (widest) instruction set on the + # running kernel: + if [ "${_cputype}" = i86pc ]; then + _cputype="$(isainfo -n)" + fi + fi + + case "${_ostype}" in + Android) + _ostype=linux-android + APP_FILTER=$(echo $APP_FILTER | sed -e "s/android|//gi") + ;; + Linux) + check_proc + _ostype=unknown-linux-${_clibtype} + _bitness=$(get_bitness) + APP_FILTER=$(echo $APP_FILTER | sed -e "s/linux|//gi") + ;; + FreeBSD) + _ostype=unknown-freebsd + ;; + NetBSD) + _ostype=unknown-netbsd + ;; + DragonFly) + _ostype=unknown-dragonfly + ;; + Darwin) + _ostype=apple-darwin + APP_FILTER=$(echo $APP_FILTER | sed -e "s/darwin|//gi") + ;; + illumos) + _ostype=unknown-illumos + ;; + MINGW* | MSYS* | CYGWIN* | Windows_NT) + _ostype=pc-windows-msvc + ;; + *) + err "unrecognized OS type: ${_ostype}" + ;; + esac + + case "${_cputype}" in + i386 | i486 | i686 | i786 | x86) + _cputype=i686 + APP_FILTER=$(echo $APP_FILTER | sed -e "s/i686|//gi") + ;; + xscale | arm) + _cputype=arm + if [ "${_ostype}" = "linux-android" ]; then + _ostype=linux-androideabi + fi + ;; + armv6l) + _cputype=arm + if [ "${_ostype}" = "linux-android" ]; then + _ostype=linux-androideabi + else + _ostype="${_ostype}eabihf" + fi + ;; + armv7l | armv8l) + _cputype=armv7 + if [ "${_ostype}" = "linux-android" ]; then + _ostype=linux-androideabi + else + _ostype="${_ostype}eabihf" + fi + ;; + aarch64 | arm64) + _cputype=aarch64 + APP_FILTER=$(echo $APP_FILTER | sed -e "s/aarch64|//gi") + APP_FILTER=$(echo $APP_FILTER | sed -e "s/arm64|//gi") + ;; + x86_64 | x86-64 | x64 | amd64) + _cputype=x86_64 + APP_FILTER=$(echo $APP_FILTER | sed -e "s/amd64|//gi") + APP_FILTER=$(echo $APP_FILTER | sed -e "s/x86_64|//gi") + APP_FILTER=$(echo $APP_FILTER | sed -e "s/x86-64|//gi") + APP_FILTER=$(echo $APP_FILTER | sed -e "s/x64|//gi") + ;; + mips) + _cputype=$(get_endianness mips '' el) + ;; + mips64) + if [ "${_bitness}" -eq 64 ]; then + # only n64 ABI is supported for now + _ostype="${_ostype}abi64" + _cputype=$(get_endianness mips64 '' el) + fi + ;; + ppc) + _cputype=powerpc + ;; + ppc64) + _cputype=powerpc64 + ;; + ppc64le) + _cputype=powerpc64le + ;; + s390x) + _cputype=s390x + ;; + riscv64) + _cputype=riscv64gc + ;; + *) + err "unknown CPU type: ${_cputype}" + ;; + esac + + # Detect 64-bit linux with 32-bit userland + if [ "${_ostype}" = unknown-linux-musl ] && [ "${_bitness}" -eq 32 ]; then + case ${_cputype} in + x86_64) + # 32-bit executable for amd64 = x32 + if is_host_amd64_elf; then { + echo "x32 userland is unsupported" 1>&2 + exit 1 + }; else + _cputype=i686 + fi + ;; + mips64) + _cputype=$(get_endianness mips '' el) + ;; + powerpc64) + _cputype=powerpc + ;; + aarch64) + _cputype=armv7 + if [ "${_ostype}" = "linux-android" ]; then + _ostype=linux-androideabi + else + _ostype="${_ostype}eabihf" + fi + ;; + riscv64gc) + err "riscv64 with 32-bit userland unsupported" + ;; + *) ;; + esac + fi + + # Detect armv7 but without the CPU features Rust needs in that build, + # and fall back to arm. + # See https://github.com/rust-lang/rustup.rs/issues/587. + if [ "${_ostype}" = "unknown-linux-musleabihf" ] && [ "${_cputype}" = armv7 ]; then + if ensure grep '^Features' /proc/cpuinfo | grep -q -v neon; then + # At least one processor does not have NEON. + _cputype=arm + fi + fi + + _arch="${_cputype}-${_ostype}" + log_debug "Detected architecture: ${_arch}" + log_debug "APP_FILTER: $APP_FILTER" + RETVAL="${_arch}" +} +function get_bitness { + need_cmd head + # Architecture detection without dependencies beyond coreutils. + # ELF files start out "\x7fELF", and the following byte is + # 0x01 for 32-bit and + # 0x02 for 64-bit. + # The printf builtin on some shells like dash only supports octal + # escape sequences, so we use those. + local _current_exe_head + _current_exe_head=$(head -c 5 /proc/self/exe) + if [ "${_current_exe_head}" = "$(printf '\177ELF\001')" ]; then + echo 32 + elif [ "${_current_exe_head}" = "$(printf '\177ELF\002')" ]; then + echo 64 + else + err "unknown platform bitness" + fi +} +function get_endianness { + local cputype=$1 + local suffix_eb=$2 + local suffix_el=$3 + + # detect endianness without od/hexdump, like get_bitness() does. + need_cmd head + need_cmd tail + + local _current_exe_endianness + _current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)" + if [ "${_current_exe_endianness}" = "$(printf '\001')" ]; then + echo "${cputype}${suffix_el}" + elif [ "${_current_exe_endianness}" = "$(printf '\002')" ]; then + echo "${cputype}${suffix_eb}" + else + err "unknown platform endianness" + fi +} +function is_host_amd64_elf() { + need_cmd head + need_cmd tail + # ELF e_machine detection without dependencies beyond coreutils. + # Two-byte field at offset 0x12 indicates the CPU, + # but we're interested in it being 0x3E to indicate amd64, or not that. + local _current_exe_machine + _current_exe_machine=$(head -c 19 /proc/self/exe | tail -c 1) + [ "${_current_exe_machine}" = "$(printf '\076')" ] +} +function check_proc() { + # Check for /proc by looking for the /proc/self/exe link. + # This is only run on Linux. + if ! test -L /proc/self/exe; then + err "unable to find /proc/self/exe. Is /proc mounted? Installation cannot proceed without /proc." + fi +} +function need_cmd() { + if ! check_cmd "$1"; then + err "need '$1' (command not found)" + fi +} +function check_cmd() { + command -v "$1" >/dev/null 2>&1 +} +function ensure() { + if ! "$@"; then err "command failed: $*"; fi +} +function assert_nz() { + if [ -z "$1" ]; then err "found empty string: $2"; fi +} + +{ + main "$@" || exit 1 +} \ No newline at end of file