Files
lbmk/include/init.sh
T
Leah Rowe bbce74d78a init.sh: MUCH safer TMPDIR handling
we previously checked whether xbmk was running a child
instance, based on the initialisation of TMPDIR, but
this relied on unreliable string substitutions, which
could not be made inherently reliable. there were also
no checks on whether the given TMPDIR, even if correct,
was a directory or whether it was a symlink; there were
also no checks on whether it changed.

now with this change, child instances are detected by
the presence of the lock file. the parent instance
writes the generated TMPDIR location in that file, and
this is checked again in the child instance, to ensure
that the TMPDIR didn't change; it also errors out if
the TMPDIR doesn't exist or if it is a symlink.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2025-08-31 20:25:00 +01:00

247 lines
7.8 KiB
Bash

# SPDX-License-Identifier: GPL-3.0-only
# Copyright (c) 2022 Caleb La Grange <thonkpeasant@protonmail.com>
# Copyright (c) 2022 Ferass El Hafidi <vitali64pmemail@protonmail.com>
# Copyright (c) 2020-2025 Leah Rowe <leah@libreboot.org>
# Copyright (c) 2025 Alper Nebi Yasak <alpernebiyasak@gmail.com>
export LC_COLLATE=C
export LC_ALL=C
projectname="libreboot"
projectsite="https://libreboot.org/"
[ -z "${PATH+x}" ] && \
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
eval "`setvars "" _nogit board reinstall versiondate aur_notice configdir \
datadir version xbmkpwd relname xbmkpwd xbtmp python pyver xbloc \
xbmklock cvxbmk cvchk xbmkpath`"
xbmk_init()
{
xbmkpwd="`pwd`" || err "Cannot generate PWD"
xbloc="$xbmkpwd/tmp"
xbmklock="$xbmkpwd/lock"
export PWD="$xbmkpwd"
[ $# -gt 0 ] && [ "$1" = "dependencies" ] && x_ xbmkpkg "$@" && exit 0
id -u 1>/dev/null 2>/dev/null || err "suid check failed (id -u)"
[ "$(id -u)" != "0" ] || err "this command as root is not permitted"
for init_cmd in get_version set_env set_threads git_init child_exec; do
xbmk_$init_cmd "$@" || break
done
}
xbmkpkg()
{
[ $# -lt 2 ] && err "fewer than two arguments"
[ $# -gt 2 ] && reinstall="$3"
eval "`setcfg "config/dependencies/$2"`"
chkvars pkg_add pkglist
x_ $pkg_add $pkglist
[ -n "$aur_notice" ] && \
printf "You need AUR packages: %s\n" "$aur_notice" 1>&2; :
}
xbmk_get_version()
{
[ ! -f ".version" ] || read -r version < ".version" || err
[ ! -f ".versiondate" ] || read -r versiondate < ".versiondate" || err
[ ! -f ".version" ] || chkvars version
[ ! -f ".versiondate" ] || chkvars versiondate
[ ! -e ".git" ] && [ ! -f ".version" ] && version="unknown"
[ ! -e ".git" ] && [ ! -f ".versiondate" ] && versiondate="1716415872"
[ -n "$version" ] && relname="$projectname-$version"; :
}
xbmk_set_env()
{
xbmkpath="$PATH"
is_child="n"
[ -f "$xbmklock" ] && is_child="y"
if [ "$is_child" = "y" ]; then
eval `setvars "" xbtmp badtmp xbtmpchk xbtmpname`
[ -z "${TMPDIR+x}" ] && export TMPDIR="/tmp"
# extremely pedantic safety checks on TMPDIR
xbtmpchk="`findpath "$TMPDIR" || err`" || err
[ "$xbtmpchk" = "${xbtmpchk#/tmp/}" ] && \
badtmp="not a subdirectory in /tmp"
[ -z "$badtmp" ] && xbtmpname="${xbtmpchk#/tmp/}" && \
[ -z "$xbtmpchk" ] && badtmp="name after /tmp is empty"
[ -z "$badtmp" ] && [ "$xbtmpname" != "${xbtmpname#*/}" ] && \
badtmp="'$TMPDIR' is a subdirectory in a subdir of /tmp"
[ -z "$badtmp" ] && [ -L "$xbtmpchk" ] && badtmp="is a symlink"
[ -z "$badtmp" ] && [ ! -d "$xbtmpchk" ] && \
badtmp="not a directory"
if [ -z "$badtmp" ]; then
# final check: check if TMPDIR changed
locktmp=""
read -r locktmp < "$xbmklock" || err "!read $xbmklock"
[ "$locktmp" = "$xbtmpchk" ] || \
badtmp="TMPDIR '$xbtmpchk' changed; was '$locktmp'"
fi
[ -n "$badtmp" ] && \
printf "bad TMPDIR initialisation, '%s': %s\n" \
"$TMPDIR" "$badtmp" 1>&2
[ -n "$badtmp" ] && err \
"'$xbmklock' present with bad tmpdir. is a build running?"
xbtmp="$xbtmpchk"
export TMPDIR="$xbtmpchk"
[ -z "${XBMK_CACHE+x}" ] && err "XBMK_CACHE unset on child"
[ -z "${XBMK_THREADS+x}" ] && xbmk_set_threads
e "lock" f missing && err "lock file absent on child"
return 1
fi
# parent instance of xbmk, so continue.
# first, set up a unified temporary directory:
export TMPDIR="/tmp"
export TMPDIR="`mktemp -d -t xbmk_XXXXXXXX || err`" || err
xbtmp="$TMPDIR"
[ -f "$xbmklock" ] && err "'$xbmklock' exists. Is a build running?"
printf "%s\n" "$xbtmp" > "$xbmklock" || \
err "cannot create '$xbmklock'"; :
export XBMK_CACHE="$xbmkpwd/cache"
[ -L "$XBMK_CACHE" ] && [ "$XBMK_CACHE" = "$xbmkpwd/cache" ] && \
err "cachedir '$xbmkpwd/cache' is a symlink"
[ ! -e "$XBMK_CACHE" ] || \
[ -d "$XBMK_CACHE" ] || err "cachedir '$XBMK_CACHE' is a file"; :
export PATH="$XBMK_CACHE/xbmkpath:$XBMK_CACHE/gnupath:$PATH"
xbmkpath="$PATH"
# if "y": a coreboot target won't be built if target.cfg says release="n"
# (this is used to exclude certain build targets from releases)
[ -z "${XBMK_RELEASE+x}" ] && export XBMK_RELEASE="n"
[ "$XBMK_RELEASE" = "Y" ] && export XBMK_RELEASE="y"
[ "$XBMK_RELEASE" = "y" ] || export XBMK_RELEASE="n"
xbmk_set_version
export LOCALVERSION="-$projectname-${version%%-*}"
remkdir "$xbtmp" "$xbloc" "$XBMK_CACHE/gnupath" "$XBMK_CACHE/xbmkpath"
xbmk_set_pyver
}
xbmk_set_threads()
{
[ -z "${XBMK_THREADS+x}" ] && export XBMK_THREADS=1
expr "X$XBMK_THREADS" : "X-\{0,1\}[0123456789][0123456789]*$" \
1>/dev/null 2>/dev/null || export XBMK_THREADS=1
}
xbmk_set_version()
{
version_="$version"
[ ! -e ".git" ] || version="$(git describe --tags HEAD 2>&1)" || \
version="git-$(git rev-parse HEAD 2>&1)" || version="$version_"
versiondate_="$versiondate"
[ ! -e ".git" ] || versiondate="$(git show --no-patch --no-notes \
--pretty='%ct' HEAD)" || versiondate="$versiondate_"
chkvars version versiondate
update_xbmkver "."
relname="$projectname-$version"
}
xbmk_set_pyver()
{
pyv="import sys; print(sys.version_info[:])"
python="python3"
pybin python3 1>/dev/null || python="python"
pyver="2" && [ "$python" = "python3" ] && pyver="3"
pybin "$python" 1>/dev/null || pyver=""
[ -z "$pyver" ] || "`pybin "$python"`" -c "$pyv" 1>/dev/null \
2>/dev/null || err "Cannot detect host Python version."
[ -n "$pyver" ] && \
pyver="$("$(pybin "$python")" -c "$pyv" | awk '{print $1}')" && \
pyver="${pyver#(}" && pyver="${pyver%,}"
[ "${pyver%%.*}" = "3" ] || err "Bad python version (must by 3.x)"
(
# set up python v3.x in PATH, in case it's not set up correctly.
# see code above that detected the correct python3 command.
x_ cd "$XBMK_CACHE/xbmkpath"
x_ ln -s "`pybin "$python"`" python
) || err "Can't set up python symlink in $XBMK_CACHE/xbmkpath"; :
}
# Use direct path, to prevent a hang if Python is using a virtual environment,
# not command -v, to prevent a hang when checking python's version
# See: https://docs.python.org/3/library/venv.html#how-venvs-work
pybin()
{
py="import sys; quit(1) if sys.prefix == sys.base_prefix else quit(0)"
venv=1
command -v "$1" 1>/dev/null 2>/dev/null || venv=0
[ $venv -lt 1 ] || "$1" -c "$py" 1>/dev/null 2>/dev/null || venv=0
# ideally, don't rely on PATH or hardcoded paths if python venv.
# use the *real*, direct executable linked to by the venv symlink
if [ $venv -gt 0 ] && [ -L "`command -v "$1" 2>/dev/null`" ]; then
pypath="$(findpath \
"$(command -v "$1" 2>/dev/null)" 2>/dev/null || :)"
[ -e "$pypath" ] && [ ! -d "$pypath" ] && \
[ -x "$pypath" ] && printf "%s\n" "$pypath" && return 0; :
fi
# if python venv: fall back to common PATH directories for checking
[ $venv -gt 0 ] && for pypath in "/usr/local/bin" "/usr/bin"; do
[ -e "$pypath/$1" ] && [ ! -d "$pypath/$1" ] && \
[ -x "$pypath/$1" ] && printf "%s/%s\n" "$pypath" "$1" && \
return 0
done && return 1
# Defer to normal command -v if not a venv
command -v "$1" 2>/dev/null || return 1
}
xbmk_git_init()
{
for gitarg in "--global user.name" "--global user.email"; do
gitcmd="git config $gitarg"; $gitcmd 1>/dev/null 2>/dev/null \
|| err "Run this first: $gitcmd \"your ${gitcmd##*.}\""
done
[ -L ".git" ] && err "'$xbmkpwd/.git' is a symlink"
[ -e ".git" ] && return 0
eval "`setvars "$(date -Rud @$versiondate)" cdate _nogit`"
x_ git init 1>/dev/null 2>/dev/null
x_ git add -A . 1>/dev/null 2>/dev/null
x_ git commit -m "$projectname $version" --date "$cdate" \
--author="xbmk <xbmk@example.com>" 1>/dev/null 2>/dev/null
x_ git tag -a "$version" -m "$projectname $version" 1>/dev/null \
2>/dev/null; :
}
xbmk_child_exec()
{
xbmk_rval=0
( x_ ./mk "$@" ) || xbmk_rval=1
( x_ rm -Rf "$xbloc" "$xbtmp" ) || xbmk_rval=1
( x_ rm -f "$xbmklock" ) || xbmk_rval=1
exit $xbmk_rval
}
xbmk_init "$@"