f2a54e3401
~/.profile works for bash, but not all other login shells. This setting PATH is a minor convenience for users, particuarly since typing on android is so much harder. The usual linux standalone bundle just expects the user to know how to add it to PATH. I don't want this code to grow special cases for every possible login shell. So displaying a message to the presumably minority who don't use bash seems like the best choice. Longer term, I'd hope termux gets some way to set an environment variable for all login shells. Systems using PAM can, via ~/.pam_environment. Or alternatively, add a git-annex package to termux, even if just an installer package. I'd rather spend time on either of those than on making this minor thing support more login shells. This commit was sponsored by mo on Patreon.
249 lines
7.5 KiB
Bash
Executable file
249 lines
7.5 KiB
Bash
Executable file
#!/bin/sh
|
|
# Runs a shell command (or interactive shell) using the binaries and
|
|
# libraries bundled with this app.
|
|
|
|
set -e
|
|
|
|
os="$(uname -o 2>/dev/null || true)"
|
|
base="$(dirname "$0")"
|
|
|
|
if [ ! -d "$base" ]; then
|
|
echo "** cannot find base directory (I seem to be $0)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -e "$base/bin/git-annex" ]; then
|
|
echo "** base directory $base does not contain bin/git-annex" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Get absolute path to base, to avoid breakage when things change directories.
|
|
orig="$(pwd)"
|
|
cd "$base"
|
|
base="$(pwd)"
|
|
cd "$orig"
|
|
|
|
# --library-path won't work if $base contains : or ;
|
|
# Detect this problem, and work around it by using a temp directory.
|
|
if echo "$base" | grep -q '[:;]'; then
|
|
tbase=$(mktemp -d -p /tmp annexshimXXXXXXXXX 2>/dev/null || true)
|
|
if [ -z "$tbase" ]; then
|
|
tbase="/tmp/annexshim.$$"
|
|
mkdir "$tbase"
|
|
fi
|
|
ln -s "$base" "$tbase/link"
|
|
base="$tbase/link"
|
|
cleanuptbase () {
|
|
rm -rf "$tbase"
|
|
}
|
|
trap cleanuptbase EXIT
|
|
else
|
|
tbase=""
|
|
fi
|
|
|
|
# Set this variable when using this script inside a package of git-annex,
|
|
# which arranges for git-annex, git-annex-shell, and git to all be in the
|
|
# standard PATH.
|
|
GIT_ANNEX_PACKAGE_INSTALL=
|
|
if [ -z "$GIT_ANNEX_PACKAGE_INSTALL" ]; then
|
|
# Install shim that's used to run git-annex-shell from ssh authorized
|
|
# keys. The assistant also does this when run, but the user may not
|
|
# be using the assistant.
|
|
if [ ! -e "$HOME/.ssh/git-annex-shell" ]; then
|
|
mkdir "$HOME/.ssh" >/dev/null 2>&1 || true
|
|
if [ -e "$HOME/.ssh" ]; then
|
|
(
|
|
echo "#!/bin/sh"
|
|
echo "set -e"
|
|
echo "if [ \"x\$SSH_ORIGINAL_COMMAND\" != \"x\" ]; then"
|
|
echo "exec '$base/runshell' git-annex-shell -c \"\$SSH_ORIGINAL_COMMAND\""
|
|
echo "else"
|
|
echo "exec '$base/runshell' git-annex-shell -c \"\$@\""
|
|
echo "fi"
|
|
) > "$HOME/.ssh/git-annex-shell"
|
|
chmod +x "$HOME/.ssh/git-annex-shell"
|
|
fi
|
|
fi
|
|
|
|
# And this shim is used by the webapp when adding a remote ssh server.
|
|
if [ ! -e "$HOME/.ssh/git-annex-wrapper" ]; then
|
|
mkdir "$HOME/.ssh" >/dev/null 2>&1 || true
|
|
if [ -e "$HOME/.ssh" ]; then
|
|
(
|
|
echo "#!/bin/sh"
|
|
echo "set -e"
|
|
echo "exec '$base/runshell' \"\$@\""
|
|
) > "$HOME/.ssh/git-annex-wrapper"
|
|
chmod +x "$HOME/.ssh/git-annex-wrapper"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Used by git-annex assistant to further install itself.
|
|
GIT_ANNEX_APP_BASE="$base"
|
|
export GIT_ANNEX_APP_BASE
|
|
|
|
# Put our binaries first, to avoid issues with out of date or incompatible
|
|
# system binaries. Extra binaries come after system path.
|
|
ORIG_PATH="$PATH"
|
|
export ORIG_PATH
|
|
PATH="$base/bin:$PATH:$base/extra"
|
|
export PATH
|
|
|
|
# These env vars are used by the shim wrapper around each binary.
|
|
for lib in $(cat "$base/libdirs"); do
|
|
GIT_ANNEX_LD_LIBRARY_PATH="$base/$lib:$GIT_ANNEX_LD_LIBRARY_PATH"
|
|
done
|
|
export GIT_ANNEX_LD_LIBRARY_PATH
|
|
GIT_ANNEX_DIR="$base"
|
|
export GIT_ANNEX_DIR
|
|
|
|
ORIG_GCONV_PATH="$GCONV_PATH"
|
|
export ORIG_GCONV_PATH
|
|
GCONV_PATH="$base/$(cat "$base/gconvdir")"
|
|
export GCONV_PATH
|
|
|
|
ORIG_GIT_EXEC_PATH="$GIT_EXEC_PATH"
|
|
export ORIG_GIT_EXEC_PATH
|
|
GIT_EXEC_PATH="$base/git-core"
|
|
export GIT_EXEC_PATH
|
|
|
|
ORIG_GIT_TEMPLATE_DIR="$GIT_TEMPLATE_DIR"
|
|
export ORIG_GIT_TEMPLATE_DIR
|
|
GIT_TEMPLATE_DIR="$base/templates"
|
|
export GIT_TEMPLATE_DIR
|
|
|
|
ORIG_MANPATH="$MANPATH"
|
|
export ORIG_MANPATH
|
|
MANPATH="$base/usr/share/man:$MANPATH"
|
|
export MANPATH
|
|
|
|
# LD_PRELOAD may interact badly with the bundled libc and other libraries,
|
|
# which may have a different subarchitecture than the preloaded library.
|
|
unset LD_PRELOAD
|
|
|
|
# Avoid using system locales, which may interact badly with bundled libc.
|
|
# (But if LOCPATH is set, don't override it, and if GIT_ANNEX_PACKAGE_INSTALL
|
|
# is set, use the system locales.)
|
|
ORIG_LOCPATH="$LOCPATH"
|
|
export ORIG_LOCPATH
|
|
if [ -z "${LOCPATH+set}" ] && [ -z "$GIT_ANNEX_PACKAGE_INSTALL" ]; then
|
|
LOCPATH="$HOME/.cache/git-annex/locales/$(echo "$base" | tr / _ )"
|
|
export LOCPATH
|
|
|
|
# Clean up locale caches when their standalone bundle no longer exists.
|
|
for localecache in $HOME/.cache/git-annex/locales/*; do
|
|
cachebase=$(cat "$localecache/base" 2>/dev/null || true)
|
|
if [ ! -d "$cachebase" ] || ! cmp "$localecache/buildid" "$cachebase/buildid" >/dev/null 2>&1 ; then
|
|
rm -rf "$localecache" 2>&1 || true
|
|
fi
|
|
done
|
|
|
|
# If the locale cache for this bundle is out of date, refresh it.
|
|
if [ -e "$LOCPATH/buildid" ] && ! cmp "$LOCPATH/buildid" "$base/buildid" >/dev/null 2>&1 ; then
|
|
rm -rf "$LOCPATH"
|
|
fi
|
|
if ! mkdir -p "$LOCPATH"; then
|
|
echo "Unable to write to $LOCPATH; can't continue!" >&2
|
|
exit 1
|
|
fi
|
|
echo "$base" > "$LOCPATH/base"
|
|
# Not using cp to avoid using the one bundled with git-annex before
|
|
# the environment is set up to run it.
|
|
cat < "$base/buildid" > "$LOCPATH/buildid"
|
|
|
|
# Generate locale definition files for the locales in use,
|
|
# using the localedef and locale files from the bundle.
|
|
# Currently only utf-8 locales are handled.
|
|
lastlocaleenv=""
|
|
for localeenv in "$LANG" "$LANGUAGE" "$LC_CTYPE" "$LC_NUMERIC" "$LC_TIME" \
|
|
"$LC_COLLATE" "$LC_MONETARY" "$LC_MESSAGES" "$LC_PAPER" \
|
|
"$LC_NAME" "$LC_ADDRESS" "$LC_TELEPHONE" "$LC_MEASUREMENT" \
|
|
"$LC_IDENTIFICATION" "$LC_ALL"; do
|
|
if [ "$localeenv" != "$lastlocaleenv" ]; then
|
|
lastlocaleenv="$localeenv"
|
|
if [ ! -d "$LOCPATH/$localeenv" ]; then
|
|
if [ "${localeenv##[!.]*.}" = "utf8" ] || [ "${localeenv##[!.]*.}" = "UTF-8" ]; then
|
|
(
|
|
rm -rf "$LOCPATH/$localeenv.new.$$" &&
|
|
mkdir -p "$LOCPATH/$localeenv.new.$$" &&
|
|
# cd to $base since localedef reads files from pwd
|
|
cd "$base" &&
|
|
# Run localedef using the bundled i18n files;
|
|
# use LANG=C to avoid it reading the system locale archive.
|
|
I18NPATH="$base/i18n" LANG=C localedef -i "${localeenv%%.*}" -c -f UTF-8 "$LOCPATH/$localeenv.new.$$" &&
|
|
mv "$LOCPATH/$localeenv.new.$$" "$LOCPATH/$localeenv"
|
|
) >/dev/null 2>/dev/null || true
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
useproot=""
|
|
case "$os" in
|
|
# Make this bundle work well on Android.
|
|
Android)
|
|
if [ -e "$base/git" ]; then
|
|
echo "Running on Android.. Tuning for optimal behavior." >&2
|
|
# The bundled git does not work well on sdcard, so delete
|
|
# it and use termux's git which works better.
|
|
cd "$base"
|
|
find . | grep git | grep -v git-annex | grep -v git-remote-tor-annex | grep -v git-remote-gcrypt | xargs rm -rf
|
|
# Use termux's uname, which knows it's on android,
|
|
# not the bundled one.
|
|
rm -f bin/uname
|
|
# Fix shell scripts to work when run inside proot.
|
|
termux-fix-shebang bin/* runshell git-annex git-annex-shell git-annex-webapp
|
|
cd "$orig"
|
|
# Save the poor Android user the typing.
|
|
if echo "$SHELL" | grep -q '/bash'; then
|
|
if ! [ -e "$HOME/.profile" ] || ! grep -q "$base" "$HOME/.profile"; then
|
|
echo "Adding git-annex to PATH for you, in $HOME/.profile"
|
|
echo 'PATH=$PATH:'"$base" >> $HOME/.profile
|
|
fi
|
|
else
|
|
echo "To use git-annex, you will need to add $base to your shell's PATH."
|
|
fi
|
|
fi
|
|
|
|
# Work around Android 8's seccomp filtering of some crucial
|
|
# system calls, using termux's version of proot.
|
|
useproot=1
|
|
|
|
# Store ssh connection caching sockets outside of sdcard.
|
|
GIT_ANNEX_TMP_DIR="$TMPDIR"
|
|
export GIT_ANNEX_TMP_DIR
|
|
|
|
GIT_ANNEX_STANDLONE_ENV="PATH GCONV_PATH MANPATH LOCPATH"
|
|
export GIT_ANNEX_STANDLONE_ENV
|
|
;;
|
|
*)
|
|
# Indicate which variables were exported above and should be cleaned
|
|
# when running non-bundled programs.
|
|
GIT_ANNEX_STANDLONE_ENV="PATH GCONV_PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR MANPATH LOCPATH"
|
|
export GIT_ANNEX_STANDLONE_ENV
|
|
;;
|
|
esac
|
|
|
|
if [ "$1" ]; then
|
|
cmd="$1"
|
|
shift 1
|
|
else
|
|
cmd=sh
|
|
fi
|
|
|
|
if [ -z "$tbase" ]; then
|
|
if [ "$useproot" ]; then
|
|
exec proot "$cmd" "$@"
|
|
else
|
|
exec "$cmd" "$@"
|
|
fi
|
|
else
|
|
# allow EXIT trap to cleanup
|
|
if [ "$useproot" ]; then
|
|
proot "$cmd" "$@"
|
|
else
|
|
"$cmd" "$@"
|
|
fi
|
|
fi
|