1.1--- a/.hgignore Mon Apr 29 22:26:53 2024 -0400
1.2+++ b/.hgignore Tue Apr 30 19:14:48 2024 -0400
1.3@@ -1,3 +1,4 @@
1.4 .*[.](fasl|lock|elc|eln|scratch|tar)$
1.5 .*(target|dist|node_modules|target-trunk|build)/.*
1.6-linux/linux-[0-9]+[.].*/.*
1.7\ No newline at end of file
1.8+linux/linux-[0-9]+[.].*/.*
1.9+host.sxp
1.10\ No newline at end of file
2.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2+++ b/Containerfile.mail Tue Apr 30 19:14:48 2024 -0400
2.3@@ -0,0 +1,1 @@
2.4+FROM stalwartlabs/mail-server:latest
2.5\ No newline at end of file
3.1--- a/bootstrap.lisp Mon Apr 29 22:26:53 2024 -0400
3.2+++ b/bootstrap.lisp Tue Apr 30 19:14:48 2024 -0400
3.3@@ -12,9 +12,10 @@
3.4 :cli/shell :std/hash-table :std/alien))
3.5 (in-package :infra/bootstrap)
3.6 (in-readtable :shell)
3.7+
3.8 (eval-when (:compile-toplevel)
3.9 (defstruct host name cpus mem os kernel core)
3.10- (defparameter *config-file* #P"config.sxp")
3.11+ (defparameter *config-file* (or (pathname (sb-posix:getenv "BUILD_PROFILE")) #P"default.sxp"))
3.12 (defparameter *build-config* (read-sxp-file *config-file*))
3.13 (defparameter *host-config* (make-host :name (sb-unix:unix-gethostname) :cpus (num-cpus) :mem #+nil (mem-total) 15815828
3.14 :os "archlinux" :kernel "linux" :core sb-ext:*core-pathname*))
4.1--- a/bootstrap.sh Mon Apr 29 22:26:53 2024 -0400
4.2+++ b/bootstrap.sh Tue Apr 30 19:14:48 2024 -0400
4.3@@ -1,1 +1,1 @@
4.4-#!/bin/sh
4.5+#!/usr/bin/env sh
5.1--- a/check.sh Mon Apr 29 22:26:53 2024 -0400
5.2+++ b/check.sh Tue Apr 30 19:14:48 2024 -0400
5.3@@ -1,1 +1,396 @@
5.4-#!/bin/sh
5.5+#!/usr/bin/env sh
5.6+set -eu
5.7+main() {
5.8+ need_cmd uname
5.9+ need_cmd mktemp
5.10+ need_cmd chmod
5.11+ need_cmd mkdir
5.12+ need_cmd rm
5.13+ need_cmd rmdir
5.14+ need_cmd tar
5.15+ need_cmd zstd
5.16+ need_cmd hg
5.17+ need_cmd git
5.18+ need_cmd clang
5.19+ need_cmd grep
5.20+ need_cmd awk
5.21+ need_cmd head
5.22+ need_cmd tail
5.23+ host_config_file=host.sxp
5.24+ rm $host_config_file
5.25+ check_mem
5.26+ check_disk
5.27+ check_mod kvm
5.28+ get_architecture || return 1
5.29+ local _arch="$RETVAL"
5.30+ assert_nz "$_arch" "arch"
5.31+ _write ";; -*- mode:skel -*-"
5.32+ _write ":arch \"$_arch\""
5.33+ kernel_version
5.34+ local _kernel_version="$RETVAL"
5.35+ _write ":kernel \"$_kernel_version\""
5.36+ check_cpus
5.37+ local _num_cpus="$RETVAL"
5.38+ _write ":cpus $_num_cpus"
5.39+ case "$_arch" in
5.40+ *windows*)
5.41+ _write ":ext \"exe\""
5.42+ ;;
5.43+ *)
5.44+ _write ":ext nil"
5.45+ esac
5.46+}
5.47+
5.48+say() {
5.49+ printf '%s\n' "$1"
5.50+}
5.51+
5.52+_write() {
5.53+ say "$1" >> $host_config_file
5.54+}
5.55+
5.56+err() {
5.57+ say "$1" >&2
5.58+ exit 1
5.59+}
5.60+
5.61+assert_nz() {
5.62+ if [ -z "$1" ]; then err "assert_nz $2"; fi
5.63+}
5.64+
5.65+check_cmd() {
5.66+ command -v "$1" > /dev/null 2>&1
5.67+}
5.68+
5.69+need_cmd() {
5.70+ if ! check_cmd "$1"; then
5.71+ err "need '$1' (command not found)"
5.72+ fi
5.73+}
5.74+
5.75+ensure() {
5.76+ if ! "$@"; then err "command failed: $*"; fi
5.77+}
5.78+
5.79+check_proc() {
5.80+ # Check for /proc by looking for the /proc/self/exe link
5.81+ # This is only run on Linux
5.82+ if ! test -L /proc/self/exe ; then
5.83+ err "fatal: Unable to find /proc/self/exe. Is /proc mounted? Installation cannot proceed without /proc."
5.84+ fi
5.85+}
5.86+
5.87+get_bitness() {
5.88+ # Architecture detection without dependencies beyond coreutils.
5.89+ # ELF files start out "\x7fELF", and the following byte is
5.90+ # 0x01 for 32-bit and
5.91+ # 0x02 for 64-bit.
5.92+ # The printf builtin on some shells like dash only supports octal
5.93+ # escape sequences, so we use those.
5.94+ local _current_exe_head
5.95+ _current_exe_head=$(head -c 5 /proc/self/exe )
5.96+ if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then
5.97+ echo 32
5.98+ elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then
5.99+ echo 64
5.100+ else
5.101+ err "unknown platform bitness"
5.102+ fi
5.103+}
5.104+
5.105+is_host_amd64_elf() {
5.106+ # ELF e_machine detection without dependencies beyond coreutils.
5.107+ # Two-byte field at offset 0x12 indicates the CPU,
5.108+ # but we're interested in it being 0x3E to indicate amd64, or not that.
5.109+ local _current_exe_machine
5.110+ _current_exe_machine=$(head -c 19 /proc/self/exe | tail -c 1)
5.111+ [ "$_current_exe_machine" = "$(printf '\076')" ]
5.112+}
5.113+
5.114+get_endianness() {
5.115+ local cputype=$1
5.116+ local suffix_eb=$2
5.117+ local suffix_el=$3
5.118+
5.119+ # detect endianness without od/hexdump, like get_bitness() does.
5.120+ local _current_exe_endianness
5.121+ _current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)"
5.122+ if [ "$_current_exe_endianness" = "$(printf '\001')" ]; then
5.123+ echo "${cputype}${suffix_el}"
5.124+ elif [ "$_current_exe_endianness" = "$(printf '\002')" ]; then
5.125+ echo "${cputype}${suffix_eb}"
5.126+ else
5.127+ err "unknown platform endianness"
5.128+ fi
5.129+}
5.130+
5.131+get_architecture() {
5.132+ local _ostype _cputype _bitness _arch _clibtype
5.133+ _ostype="$(uname -s)"
5.134+ _cputype="$(uname -m)"
5.135+ _clibtype="gnu"
5.136+
5.137+ if [ "$_ostype" = Linux ]; then
5.138+ if [ "$(uname -o)" = Android ]; then
5.139+ _ostype=Android
5.140+ fi
5.141+ if ldd --version 2>&1 | grep -q 'musl'; then
5.142+ _clibtype="musl"
5.143+ fi
5.144+ fi
5.145+
5.146+ if [ "$_ostype" = Darwin ] && [ "$_cputype" = i386 ]; then
5.147+ # Darwin `uname -m` lies
5.148+ if sysctl hw.optional.x86_64 | grep -q ': 1'; then
5.149+ _cputype=x86_64
5.150+ fi
5.151+ fi
5.152+
5.153+ if [ "$_ostype" = SunOS ]; then
5.154+ # Both Solaris and illumos presently announce as "SunOS" in "uname -s"
5.155+ # so use "uname -o" to disambiguate. We use the full path to the
5.156+ # system uname in case the user has coreutils uname first in PATH,
5.157+ # which has historically sometimes printed the wrong value here.
5.158+ if [ "$(/usr/bin/uname -o)" = illumos ]; then
5.159+ _ostype=illumos
5.160+ fi
5.161+
5.162+ # illumos systems have multi-arch userlands, and "uname -m" reports the
5.163+ # machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86
5.164+ # systems. Check for the native (widest) instruction set on the
5.165+ # running kernel:
5.166+ if [ "$_cputype" = i86pc ]; then
5.167+ _cputype="$(isainfo -n)"
5.168+ fi
5.169+ fi
5.170+
5.171+ case "$_ostype" in
5.172+
5.173+ Android)
5.174+ _ostype=linux-android
5.175+ ;;
5.176+
5.177+ Linux)
5.178+ check_proc
5.179+ _ostype=unknown-linux-$_clibtype
5.180+ _bitness=$(get_bitness)
5.181+ ;;
5.182+
5.183+ FreeBSD)
5.184+ _ostype=unknown-freebsd
5.185+ ;;
5.186+
5.187+ NetBSD)
5.188+ _ostype=unknown-netbsd
5.189+ ;;
5.190+
5.191+ DragonFly)
5.192+ _ostype=unknown-dragonfly
5.193+ ;;
5.194+
5.195+ Darwin)
5.196+ _ostype=apple-darwin
5.197+ ;;
5.198+
5.199+ illumos)
5.200+ _ostype=unknown-illumos
5.201+ ;;
5.202+
5.203+ MINGW* | MSYS* | CYGWIN* | Windows_NT)
5.204+ _ostype=pc-windows-gnu
5.205+ ;;
5.206+
5.207+ *)
5.208+ err "unrecognized OS type: $_ostype"
5.209+ ;;
5.210+
5.211+ esac
5.212+
5.213+ case "$_cputype" in
5.214+
5.215+ i386 | i486 | i686 | i786 | x86)
5.216+ _cputype=i686
5.217+ ;;
5.218+
5.219+ xscale | arm)
5.220+ _cputype=arm
5.221+ if [ "$_ostype" = "linux-android" ]; then
5.222+ _ostype=linux-androideabi
5.223+ fi
5.224+ ;;
5.225+
5.226+ armv6l)
5.227+ _cputype=arm
5.228+ if [ "$_ostype" = "linux-android" ]; then
5.229+ _ostype=linux-androideabi
5.230+ else
5.231+ _ostype="${_ostype}eabihf"
5.232+ fi
5.233+ ;;
5.234+
5.235+ armv7l | armv8l)
5.236+ _cputype=armv7
5.237+ if [ "$_ostype" = "linux-android" ]; then
5.238+ _ostype=linux-androideabi
5.239+ else
5.240+ _ostype="${_ostype}eabihf"
5.241+ fi
5.242+ ;;
5.243+
5.244+ aarch64 | arm64)
5.245+ _cputype=aarch64
5.246+ ;;
5.247+
5.248+ x86_64 | x86-64 | x64 | amd64)
5.249+ _cputype=x86_64
5.250+ ;;
5.251+
5.252+ mips)
5.253+ _cputype=$(get_endianness mips '' el)
5.254+ ;;
5.255+
5.256+ mips64)
5.257+ if [ "$_bitness" -eq 64 ]; then
5.258+ # only n64 ABI is supported for now
5.259+ _ostype="${_ostype}abi64"
5.260+ _cputype=$(get_endianness mips64 '' el)
5.261+ fi
5.262+ ;;
5.263+
5.264+ ppc)
5.265+ _cputype=powerpc
5.266+ ;;
5.267+
5.268+ ppc64)
5.269+ _cputype=powerpc64
5.270+ ;;
5.271+
5.272+ ppc64le)
5.273+ _cputype=powerpc64le
5.274+ ;;
5.275+
5.276+ s390x)
5.277+ _cputype=s390x
5.278+ ;;
5.279+ riscv64)
5.280+ _cputype=riscv64gc
5.281+ ;;
5.282+ loongarch64)
5.283+ _cputype=loongarch64
5.284+ ;;
5.285+ *)
5.286+ err "unknown CPU type: $_cputype"
5.287+
5.288+ esac
5.289+
5.290+ # Detect 64-bit linux with 32-bit userland
5.291+ if [ "${_ostype}" = unknown-linux-gnu ] && [ "${_bitness}" -eq 32 ]; then
5.292+ case $_cputype in
5.293+ x86_64)
5.294+ if [ -n "${CPUTYPE:-}" ]; then
5.295+ _cputype="$CPUTYPE"
5.296+ else {
5.297+ # 32-bit executable for amd64 = x32
5.298+ if is_host_amd64_elf; then {
5.299+ echo "This host is running an x32 userland; as it stands, x32 support is poor," 1>&2
5.300+ echo "and there isn't a native toolchain -- you will have to install" 1>&2
5.301+ echo "multiarch compatibility with i686 and/or amd64, then select one" 1>&2
5.302+ echo "by re-running this script with the CPUTYPE environment variable" 1>&2
5.303+ echo "set to i686 or x86_64, respectively." 1>&2
5.304+ exit 1
5.305+ }; else
5.306+ _cputype=i686
5.307+ fi
5.308+ }; fi
5.309+ ;;
5.310+ mips64)
5.311+ _cputype=$(get_endianness mips '' el)
5.312+ ;;
5.313+ powerpc64)
5.314+ _cputype=powerpc
5.315+ ;;
5.316+ aarch64)
5.317+ _cputype=armv7
5.318+ if [ "$_ostype" = "linux-android" ]; then
5.319+ _ostype=linux-androideabi
5.320+ else
5.321+ _ostype="${_ostype}eabihf"
5.322+ fi
5.323+ ;;
5.324+ riscv64gc)
5.325+ err "riscv64 with 32-bit userland unsupported"
5.326+ ;;
5.327+ esac
5.328+ fi
5.329+
5.330+ if [ "$_ostype" = "unknown-linux-gnueabihf" ] && [ "$_cputype" = armv7 ]; then
5.331+ if ensure grep '^Features' /proc/cpuinfo | grep -q -v neon; then
5.332+ # At least one processor does not have NEON.
5.333+ _cputype=arm
5.334+ fi
5.335+ fi
5.336+
5.337+ _arch="${_cputype}-${_ostype}"
5.338+
5.339+ RETVAL="$_arch"
5.340+}
5.341+
5.342+mem_total () {
5.343+ local _mem_total
5.344+ _mem_total=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
5.345+ RETVAL="$_mem_total"
5.346+}
5.347+
5.348+check_mem () {
5.349+ mem_total
5.350+ local _mem_total="$RETVAL"
5.351+ local _mem_min=8388608 # 8Gb in kB
5.352+ if [ "$_mem_total" -lt "$_mem_min" ]; then
5.353+ err "not enough memory: $_mem_total < $_mem_min";
5.354+ fi
5.355+}
5.356+
5.357+disk_free () {
5.358+ local _disk_free
5.359+ _disk_free=$(df -kh . | tail -n1 | awk '{print $4}')
5.360+ RETVAL="${_disk_free%?}"
5.361+}
5.362+
5.363+check_disk () {
5.364+ disk_free
5.365+ local _disk_free="$RETVAL"
5.366+ local _disk_min=32 # in Gigabytes
5.367+ if [ "$_disk_free" -lt "$_disk_min" ]; then
5.368+ err "not enough disk space: $_disk_free < $_disk_min"
5.369+ fi
5.370+}
5.371+
5.372+kernel_version () {
5.373+ local _kernel_version
5.374+ _kernel_version=$(uname -r)
5.375+ RETVAL="$_kernel_version"
5.376+}
5.377+
5.378+check_mod () {
5.379+ if ! lsmod | grep -wq "$1"; then
5.380+ err "kernel module $1 isn't loaded"
5.381+ fi
5.382+}
5.383+
5.384+num_cpus () {
5.385+ local _num_cpus
5.386+ _num_cpus=$(grep -c '^processor' /proc/cpuinfo 2>/dev/null)
5.387+ RETVAL="$_num_cpus"
5.388+ # sysctl -n hw.ncpu # nproc --all
5.389+}
5.390+
5.391+check_cpus () {
5.392+ num_cpus
5.393+ local _num_cpus="$RETVAL"
5.394+ local _min_cpus=8
5.395+ if [ "$_num_cpus" -lt "$_min_cpus" ]; then
5.396+ err "not enough cpu threads ($_num_cpus < $_min_cpus)"
5.397+ fi
5.398+}
5.399+
5.400+main "$@" || exit 1
6.1--- a/config.sh Mon Apr 29 22:26:53 2024 -0400
6.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3@@ -1,1 +0,0 @@
6.4-#!/bin/sh
7.1--- a/config.sxp Mon Apr 29 22:26:53 2024 -0400
7.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3@@ -1,13 +0,0 @@
7.4-;; -*- mode:skel -*-
7.5-:sbcl-version "2.4.4"
7.6-:stash ".stash"
7.7-:dist nil
7.8-:install-root "/usr/local"
7.9-:log-level :debug
7.10-:features (:sbcl
7.11- :sbcl-docs
7.12- :rust :cargo-tools
7.13- :tree-sitter :tree-sitter-langs
7.14- :skel :packy
7.15- :emacs-mini)
7.16-
8.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2+++ b/default.sxp Tue Apr 30 19:14:48 2024 -0400
8.3@@ -0,0 +1,13 @@
8.4+;; -*- mode:skel -*-
8.5+:sbcl-version "2.4.4"
8.6+:stash ".stash"
8.7+:dist nil
8.8+:install-root "/usr/local"
8.9+:log-level :debug
8.10+:features
8.11+(:sbcl
8.12+ :sbcl-docs
8.13+ :rust :cargo-tools
8.14+ :tree-sitter :tree-sitter-langs
8.15+ :skel :packy
8.16+ :emacs-mini)
9.1--- a/install.sh Mon Apr 29 22:26:53 2024 -0400
9.2+++ b/install.sh Tue Apr 30 19:14:48 2024 -0400
9.3@@ -1,1 +1,577 @@
9.4 #!/bin/sh
9.5+set -eu
9.6+main() {
9.7+ downloader --check
9.8+ need_cmd uname
9.9+ need_cmd mktemp
9.10+ need_cmd chmod
9.11+ need_cmd mkdir
9.12+ need_cmd rm
9.13+ need_cmd rmdir
9.14+ get_architecture || return 1
9.15+ local _arch="$RETVAL"
9.16+ assert_nz "$_arch" "arch"
9.17+ local _ext=""
9.18+ case "$_arch" in
9.19+ *windows*)
9.20+ _ext=".exe"
9.21+ ;;
9.22+ esac
9.23+ local _url="https://packy.compiler.company/dist/${_arch}/cc-install${_ext}"
9.24+ local _dir
9.25+ if ! _dir="$(ensure mktemp -d)"; then
9.26+ # Because the previous command ran in a subshell, we must manually
9.27+ # propagate exit status.
9.28+ exit 1
9.29+ fi
9.30+ local _file="${_dir}/cc-install${_ext}"
9.31+ printf '%s\n' 'info: installing artifacts...' 1>&2
9.32+ ensure mkdir -p "$_dir"
9.33+ ensure downloader "$_url" "$_file" "$_arch"
9.34+ ensure chmod u+x "$_file"
9.35+ if [ ! -x "$_file" ]; then
9.36+ printf '%s\n' "Cannot execute $_file (likely because of mounting /tmp as noexec)." 1>&2
9.37+ printf '%s\n' "Please copy the file to a location where you can execute binaries and run ./cc-install${_ext}." 1>&2
9.38+ exit 1
9.39+ fi
9.40+ "$_file" "$@"
9.41+ local _retval=$?
9.42+ rm "$_file"
9.43+ rmdir "$_dir"
9.44+ return "$_retval"
9.45+}
9.46+
9.47+say() {
9.48+ printf 'compiler.company: %s\n' "$1"
9.49+}
9.50+
9.51+err() {
9.52+ say "$1" >&2
9.53+ exit 1
9.54+}
9.55+
9.56+assert_nz() {
9.57+ if [ -z "$1" ]; then err "assert_nz $2"; fi
9.58+}
9.59+
9.60+check_cmd() {
9.61+ command -v "$1" > /dev/null 2>&1
9.62+}
9.63+
9.64+need_cmd() {
9.65+ if ! check_cmd "$1"; then
9.66+ err "need '$1' (command not found)"
9.67+ fi
9.68+}
9.69+
9.70+# Run a command that should never fail. If the command fails execution
9.71+# will immediately terminate with an error showing the failing
9.72+# command.
9.73+ensure() {
9.74+ if ! "$@"; then err "command failed: $*"; fi
9.75+}
9.76+
9.77+# Check if curl supports the --retry flag, then pass it to the curl invocation.
9.78+check_curl_for_retry_support() {
9.79+ local _retry_supported=""
9.80+ # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
9.81+ if check_help_for "notspecified" "curl" "--retry"; then
9.82+ _retry_supported="--retry 3"
9.83+ if check_help_for "notspecified" "curl" "--continue-at"; then
9.84+ # "-C -" tells curl to automatically find where to resume the download when retrying.
9.85+ _retry_supported="--retry 3 -C -"
9.86+ fi
9.87+ fi
9.88+
9.89+ RETVAL="$_retry_supported"
9.90+}
9.91+
9.92+# Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites
9.93+# if support by local tools is detected. Detection currently supports these curl backends:
9.94+# GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty.
9.95+get_ciphersuites_for_curl() {
9.96+ if [ -n "${TLS_CIPHERSUITES-}" ]; then
9.97+ # user specified custom cipher suites, assume they know what they're doing
9.98+ RETVAL="$TLS_CIPHERSUITES"
9.99+ return
9.100+ fi
9.101+
9.102+ local _openssl_syntax="no"
9.103+ local _gnutls_syntax="no"
9.104+ local _backend_supported="yes"
9.105+ if curl -V | grep -q ' OpenSSL/'; then
9.106+ _openssl_syntax="yes"
9.107+ elif curl -V | grep -iq ' LibreSSL/'; then
9.108+ _openssl_syntax="yes"
9.109+ elif curl -V | grep -iq ' BoringSSL/'; then
9.110+ _openssl_syntax="yes"
9.111+ elif curl -V | grep -iq ' GnuTLS/'; then
9.112+ _gnutls_syntax="yes"
9.113+ else
9.114+ _backend_supported="no"
9.115+ fi
9.116+
9.117+ local _args_supported="no"
9.118+ if [ "$_backend_supported" = "yes" ]; then
9.119+ # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
9.120+ if check_help_for "notspecified" "curl" "--tlsv1.2" "--ciphers" "--proto"; then
9.121+ _args_supported="yes"
9.122+ fi
9.123+ fi
9.124+
9.125+ local _cs=""
9.126+ if [ "$_args_supported" = "yes" ]; then
9.127+ if [ "$_openssl_syntax" = "yes" ]; then
9.128+ _cs=$(get_strong_ciphersuites_for "openssl")
9.129+ elif [ "$_gnutls_syntax" = "yes" ]; then
9.130+ _cs=$(get_strong_ciphersuites_for "gnutls")
9.131+ fi
9.132+ fi
9.133+
9.134+ RETVAL="$_cs"
9.135+}
9.136+
9.137+# Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites
9.138+# if support by local tools is detected. Detection currently supports these wget backends:
9.139+# GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty.
9.140+get_ciphersuites_for_wget() {
9.141+ if [ -n "${TLS_CIPHERSUITES-}" ]; then
9.142+ # user specified custom cipher suites, assume they know what they're doing
9.143+ RETVAL="$TLS_CIPHERSUITES"
9.144+ return
9.145+ fi
9.146+
9.147+ local _cs=""
9.148+ if wget -V | grep -q '\-DHAVE_LIBSSL'; then
9.149+ # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
9.150+ if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then
9.151+ _cs=$(get_strong_ciphersuites_for "openssl")
9.152+ fi
9.153+ elif wget -V | grep -q '\-DHAVE_LIBGNUTLS'; then
9.154+ # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
9.155+ if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then
9.156+ _cs=$(get_strong_ciphersuites_for "gnutls")
9.157+ fi
9.158+ fi
9.159+
9.160+ RETVAL="$_cs"
9.161+}
9.162+
9.163+check_help_for() {
9.164+ local _arch
9.165+ local _cmd
9.166+ local _arg
9.167+ _arch="$1"
9.168+ shift
9.169+ _cmd="$1"
9.170+ shift
9.171+
9.172+ local _category
9.173+ if "$_cmd" --help | grep -q 'For all options use the manual or "--help all".'; then
9.174+ _category="all"
9.175+ else
9.176+ _category=""
9.177+ fi
9.178+
9.179+ case "$_arch" in
9.180+
9.181+ *darwin*)
9.182+ if check_cmd sw_vers; then
9.183+ case $(sw_vers -productVersion) in
9.184+ 10.*)
9.185+ # If we're running on macOS, older than 10.13, then we always
9.186+ # fail to find these options to force fallback
9.187+ if [ "$(sw_vers -productVersion | cut -d. -f2)" -lt 13 ]; then
9.188+ # Older than 10.13
9.189+ echo "Warning: Detected macOS platform older than 10.13"
9.190+ return 1
9.191+ fi
9.192+ ;;
9.193+ 11.*)
9.194+ # We assume Big Sur will be OK for now
9.195+ ;;
9.196+ *)
9.197+ # Unknown product version, warn and continue
9.198+ echo "Warning: Detected unknown macOS major version: $(sw_vers -productVersion)"
9.199+ echo "Warning TLS capabilities detection may fail"
9.200+ ;;
9.201+ esac
9.202+ fi
9.203+ ;;
9.204+
9.205+ esac
9.206+
9.207+ for _arg in "$@"; do
9.208+ if ! "$_cmd" --help "$_category" | grep -q -- "$_arg"; then
9.209+ return 1
9.210+ fi
9.211+ done
9.212+
9.213+ true # not strictly needed
9.214+}
9.215+
9.216+# Return strong TLS 1.2-1.3 cipher suites in OpenSSL or GnuTLS syntax. TLS 1.2
9.217+# excludes non-ECDHE and non-AEAD cipher suites. DHE is excluded due to bad
9.218+# DH params often found on servers (see RFC 7919). Sequence matches or is
9.219+# similar to Firefox 68 ESR with weak cipher suites disabled via about:config.
9.220+# $1 must be openssl or gnutls.
9.221+get_strong_ciphersuites_for() {
9.222+ if [ "$1" = "openssl" ]; then
9.223+ # OpenSSL is forgiving of unknown values, no problems with TLS 1.3 values on versions that don't support it yet.
9.224+ echo "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384"
9.225+ elif [ "$1" = "gnutls" ]; then
9.226+ # GnuTLS isn't forgiving of unknown values, so this may require a GnuTLS version that supports TLS 1.3 even if wget doesn't.
9.227+ # Begin with SECURE128 (and higher) then remove/add to build cipher suites. Produces same 9 cipher suites as OpenSSL but in slightly different order.
9.228+ echo "SECURE128:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1:-VERS-DTLS-ALL:-CIPHER-ALL:-MAC-ALL:-KX-ALL:+AEAD:+ECDHE-ECDSA:+ECDHE-RSA:+AES-128-GCM:+CHACHA20-POLY1305:+AES-256-GCM"
9.229+ fi
9.230+}
9.231+
9.232+check_proc() {
9.233+ # Check for /proc by looking for the /proc/self/exe link
9.234+ # This is only run on Linux
9.235+ if ! test -L /proc/self/exe ; then
9.236+ err "fatal: Unable to find /proc/self/exe. Is /proc mounted? Installation cannot proceed without /proc."
9.237+ fi
9.238+}
9.239+
9.240+get_bitness() {
9.241+ need_cmd head
9.242+ # Architecture detection without dependencies beyond coreutils.
9.243+ # ELF files start out "\x7fELF", and the following byte is
9.244+ # 0x01 for 32-bit and
9.245+ # 0x02 for 64-bit.
9.246+ # The printf builtin on some shells like dash only supports octal
9.247+ # escape sequences, so we use those.
9.248+ local _current_exe_head
9.249+ _current_exe_head=$(head -c 5 /proc/self/exe )
9.250+ if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then
9.251+ echo 32
9.252+ elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then
9.253+ echo 64
9.254+ else
9.255+ err "unknown platform bitness"
9.256+ fi
9.257+}
9.258+
9.259+is_host_amd64_elf() {
9.260+ need_cmd head
9.261+ need_cmd tail
9.262+ # ELF e_machine detection without dependencies beyond coreutils.
9.263+ # Two-byte field at offset 0x12 indicates the CPU,
9.264+ # but we're interested in it being 0x3E to indicate amd64, or not that.
9.265+ local _current_exe_machine
9.266+ _current_exe_machine=$(head -c 19 /proc/self/exe | tail -c 1)
9.267+ [ "$_current_exe_machine" = "$(printf '\076')" ]
9.268+}
9.269+
9.270+get_endianness() {
9.271+ local cputype=$1
9.272+ local suffix_eb=$2
9.273+ local suffix_el=$3
9.274+
9.275+ # detect endianness without od/hexdump, like get_bitness() does.
9.276+ need_cmd head
9.277+ need_cmd tail
9.278+
9.279+ local _current_exe_endianness
9.280+ _current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)"
9.281+ if [ "$_current_exe_endianness" = "$(printf '\001')" ]; then
9.282+ echo "${cputype}${suffix_el}"
9.283+ elif [ "$_current_exe_endianness" = "$(printf '\002')" ]; then
9.284+ echo "${cputype}${suffix_eb}"
9.285+ else
9.286+ err "unknown platform endianness"
9.287+ fi
9.288+}
9.289+
9.290+get_architecture() {
9.291+ local _ostype _cputype _bitness _arch _clibtype
9.292+ _ostype="$(uname -s)"
9.293+ _cputype="$(uname -m)"
9.294+ _clibtype="gnu"
9.295+
9.296+ if [ "$_ostype" = Linux ]; then
9.297+ if [ "$(uname -o)" = Android ]; then
9.298+ _ostype=Android
9.299+ fi
9.300+ if ldd --version 2>&1 | grep -q 'musl'; then
9.301+ _clibtype="musl"
9.302+ fi
9.303+ fi
9.304+
9.305+ if [ "$_ostype" = Darwin ] && [ "$_cputype" = i386 ]; then
9.306+ # Darwin `uname -m` lies
9.307+ if sysctl hw.optional.x86_64 | grep -q ': 1'; then
9.308+ _cputype=x86_64
9.309+ fi
9.310+ fi
9.311+
9.312+ if [ "$_ostype" = SunOS ]; then
9.313+ # Both Solaris and illumos presently announce as "SunOS" in "uname -s"
9.314+ # so use "uname -o" to disambiguate. We use the full path to the
9.315+ # system uname in case the user has coreutils uname first in PATH,
9.316+ # which has historically sometimes printed the wrong value here.
9.317+ if [ "$(/usr/bin/uname -o)" = illumos ]; then
9.318+ _ostype=illumos
9.319+ fi
9.320+
9.321+ # illumos systems have multi-arch userlands, and "uname -m" reports the
9.322+ # machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86
9.323+ # systems. Check for the native (widest) instruction set on the
9.324+ # running kernel:
9.325+ if [ "$_cputype" = i86pc ]; then
9.326+ _cputype="$(isainfo -n)"
9.327+ fi
9.328+ fi
9.329+
9.330+ case "$_ostype" in
9.331+
9.332+ Android)
9.333+ _ostype=linux-android
9.334+ ;;
9.335+
9.336+ Linux)
9.337+ check_proc
9.338+ _ostype=unknown-linux-$_clibtype
9.339+ _bitness=$(get_bitness)
9.340+ ;;
9.341+
9.342+ FreeBSD)
9.343+ _ostype=unknown-freebsd
9.344+ ;;
9.345+
9.346+ NetBSD)
9.347+ _ostype=unknown-netbsd
9.348+ ;;
9.349+
9.350+ DragonFly)
9.351+ _ostype=unknown-dragonfly
9.352+ ;;
9.353+
9.354+ Darwin)
9.355+ _ostype=apple-darwin
9.356+ ;;
9.357+
9.358+ illumos)
9.359+ _ostype=unknown-illumos
9.360+ ;;
9.361+
9.362+ MINGW* | MSYS* | CYGWIN* | Windows_NT)
9.363+ _ostype=pc-windows-gnu
9.364+ ;;
9.365+
9.366+ *)
9.367+ err "unrecognized OS type: $_ostype"
9.368+ ;;
9.369+
9.370+ esac
9.371+
9.372+ case "$_cputype" in
9.373+
9.374+ i386 | i486 | i686 | i786 | x86)
9.375+ _cputype=i686
9.376+ ;;
9.377+
9.378+ xscale | arm)
9.379+ _cputype=arm
9.380+ if [ "$_ostype" = "linux-android" ]; then
9.381+ _ostype=linux-androideabi
9.382+ fi
9.383+ ;;
9.384+
9.385+ armv6l)
9.386+ _cputype=arm
9.387+ if [ "$_ostype" = "linux-android" ]; then
9.388+ _ostype=linux-androideabi
9.389+ else
9.390+ _ostype="${_ostype}eabihf"
9.391+ fi
9.392+ ;;
9.393+
9.394+ armv7l | armv8l)
9.395+ _cputype=armv7
9.396+ if [ "$_ostype" = "linux-android" ]; then
9.397+ _ostype=linux-androideabi
9.398+ else
9.399+ _ostype="${_ostype}eabihf"
9.400+ fi
9.401+ ;;
9.402+
9.403+ aarch64 | arm64)
9.404+ _cputype=aarch64
9.405+ ;;
9.406+
9.407+ x86_64 | x86-64 | x64 | amd64)
9.408+ _cputype=x86_64
9.409+ ;;
9.410+
9.411+ mips)
9.412+ _cputype=$(get_endianness mips '' el)
9.413+ ;;
9.414+
9.415+ mips64)
9.416+ if [ "$_bitness" -eq 64 ]; then
9.417+ # only n64 ABI is supported for now
9.418+ _ostype="${_ostype}abi64"
9.419+ _cputype=$(get_endianness mips64 '' el)
9.420+ fi
9.421+ ;;
9.422+
9.423+ ppc)
9.424+ _cputype=powerpc
9.425+ ;;
9.426+
9.427+ ppc64)
9.428+ _cputype=powerpc64
9.429+ ;;
9.430+
9.431+ ppc64le)
9.432+ _cputype=powerpc64le
9.433+ ;;
9.434+
9.435+ s390x)
9.436+ _cputype=s390x
9.437+ ;;
9.438+ riscv64)
9.439+ _cputype=riscv64gc
9.440+ ;;
9.441+ loongarch64)
9.442+ _cputype=loongarch64
9.443+ ;;
9.444+ *)
9.445+ err "unknown CPU type: $_cputype"
9.446+
9.447+ esac
9.448+
9.449+ # Detect 64-bit linux with 32-bit userland
9.450+ if [ "${_ostype}" = unknown-linux-gnu ] && [ "${_bitness}" -eq 32 ]; then
9.451+ case $_cputype in
9.452+ x86_64)
9.453+ if [ -n "${CPUTYPE:-}" ]; then
9.454+ _cputype="$CPUTYPE"
9.455+ else {
9.456+ # 32-bit executable for amd64 = x32
9.457+ if is_host_amd64_elf; then {
9.458+ echo "This host is running an x32 userland; as it stands, x32 support is poor," 1>&2
9.459+ echo "and there isn't a native toolchain -- you will have to install" 1>&2
9.460+ echo "multiarch compatibility with i686 and/or amd64, then select one" 1>&2
9.461+ echo "by re-running this script with the CPUTYPE environment variable" 1>&2
9.462+ echo "set to i686 or x86_64, respectively." 1>&2
9.463+ exit 1
9.464+ }; else
9.465+ _cputype=i686
9.466+ fi
9.467+ }; fi
9.468+ ;;
9.469+ mips64)
9.470+ _cputype=$(get_endianness mips '' el)
9.471+ ;;
9.472+ powerpc64)
9.473+ _cputype=powerpc
9.474+ ;;
9.475+ aarch64)
9.476+ _cputype=armv7
9.477+ if [ "$_ostype" = "linux-android" ]; then
9.478+ _ostype=linux-androideabi
9.479+ else
9.480+ _ostype="${_ostype}eabihf"
9.481+ fi
9.482+ ;;
9.483+ riscv64gc)
9.484+ err "riscv64 with 32-bit userland unsupported"
9.485+ ;;
9.486+ esac
9.487+ fi
9.488+
9.489+ if [ "$_ostype" = "unknown-linux-gnueabihf" ] && [ "$_cputype" = armv7 ]; then
9.490+ if ensure grep '^Features' /proc/cpuinfo | grep -q -v neon; then
9.491+ # At least one processor does not have NEON.
9.492+ _cputype=arm
9.493+ fi
9.494+ fi
9.495+
9.496+ _arch="${_cputype}-${_ostype}"
9.497+
9.498+ RETVAL="$_arch"
9.499+}
9.500+
9.501+# This wraps curl or wget. Try curl first, if not installed,
9.502+# use wget instead.
9.503+downloader() {
9.504+ local _dld
9.505+ local _ciphersuites
9.506+ local _err
9.507+ local _status
9.508+ local _retry
9.509+ if check_cmd curl; then
9.510+ _dld=curl
9.511+ elif check_cmd wget; then
9.512+ _dld=wget
9.513+ else
9.514+ _dld='curl or wget' # to be used in error message of need_cmd
9.515+ fi
9.516+
9.517+ if [ "$1" = --check ]; then
9.518+ need_cmd "$_dld"
9.519+ elif [ "$_dld" = curl ]; then
9.520+ check_curl_for_retry_support
9.521+ _retry="$RETVAL"
9.522+ get_ciphersuites_for_curl
9.523+ _ciphersuites="$RETVAL"
9.524+ if [ -n "$_ciphersuites" ]; then
9.525+ _err=$(curl $_retry --proto '=https' --tlsv1.2 --ciphers "$_ciphersuites" --silent --show-error --fail --location "$1" --output "$2" 2>&1)
9.526+ _status=$?
9.527+ else
9.528+ echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure"
9.529+ if ! check_help_for "$3" curl --proto --tlsv1.2; then
9.530+ echo "Warning: Not enforcing TLS v1.2, this is potentially less secure"
9.531+ _err=$(curl $_retry --silent --show-error --fail --location "$1" --output "$2" 2>&1)
9.532+ _status=$?
9.533+ else
9.534+ _err=$(curl $_retry --proto '=https' --tlsv1.2 --silent --show-error --fail --location "$1" --output "$2" 2>&1)
9.535+ _status=$?
9.536+ fi
9.537+ fi
9.538+ if [ -n "$_err" ]; then
9.539+ echo "$_err" >&2
9.540+ if echo "$_err" | grep -q 404$; then
9.541+ err "installer for platform '$3' not found, this may be unsupported"
9.542+ fi
9.543+ fi
9.544+ return $_status
9.545+ elif [ "$_dld" = wget ]; then
9.546+ if [ "$(wget -V 2>&1|head -2|tail -1|cut -f1 -d" ")" = "BusyBox" ]; then
9.547+ echo "Warning: using the BusyBox version of wget. Not enforcing strong cipher suites for TLS or TLS v1.2, this is potentially less secure"
9.548+ _err=$(wget "$1" -O "$2" 2>&1)
9.549+ _status=$?
9.550+ else
9.551+ get_ciphersuites_for_wget
9.552+ _ciphersuites="$RETVAL"
9.553+ if [ -n "$_ciphersuites" ]; then
9.554+ _err=$(wget --https-only --secure-protocol=TLSv1_2 --ciphers "$_ciphersuites" "$1" -O "$2" 2>&1)
9.555+ _status=$?
9.556+ else
9.557+ echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure"
9.558+ if ! check_help_for "$3" wget --https-only --secure-protocol; then
9.559+ echo "Warning: Not enforcing TLS v1.2, this is potentially less secure"
9.560+ _err=$(wget "$1" -O "$2" 2>&1)
9.561+ _status=$?
9.562+ else
9.563+ _err=$(wget --https-only --secure-protocol=TLSv1_2 "$1" -O "$2" 2>&1)
9.564+ _status=$?
9.565+ fi
9.566+ fi
9.567+ fi
9.568+ if [ -n "$_err" ]; then
9.569+ echo "$_err" >&2
9.570+ if echo "$_err" | grep -q ' 404 Not Found$'; then
9.571+ err "installer for platform '$3' not found, this may be unsupported"
9.572+ fi
9.573+ fi
9.574+ return $_status
9.575+ else
9.576+ err "Unknown downloader" # should not reach here
9.577+ fi
9.578+}
9.579+
9.580+main "$@" || exit 1
10.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2+++ b/profile.sh Tue Apr 30 19:14:48 2024 -0400
10.3@@ -0,0 +1,1 @@
10.4+#!/bin/sh