2012-09-28 23:08:13 +00:00
|
|
|
#!/bin/sh
|
|
|
|
# Runs a shell command (or interactive shell) using the binaries and
|
|
|
|
# libraries bundled with this app.
|
|
|
|
|
2020-08-03 17:43:21 +00:00
|
|
|
# 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. This also makes the system locales be used.
|
|
|
|
GIT_ANNEX_PACKAGE_INSTALL=
|
|
|
|
|
2012-09-28 23:08:13 +00:00
|
|
|
set -e
|
|
|
|
|
2020-07-24 18:46:50 +00:00
|
|
|
orig_IFS="${IFS}"
|
|
|
|
unset IFS
|
|
|
|
|
2018-04-25 17:47:43 +00:00
|
|
|
os="$(uname -o 2>/dev/null || true)"
|
2013-03-20 18:11:36 +00:00
|
|
|
base="$(dirname "$0")"
|
2012-09-28 23:08:13 +00:00
|
|
|
|
|
|
|
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"
|
|
|
|
|
2015-08-04 20:08:19 +00:00
|
|
|
# --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
|
2018-05-05 12:55:50 +00:00
|
|
|
else
|
|
|
|
tbase=""
|
2015-08-04 20:08:19 +00:00
|
|
|
fi
|
|
|
|
|
2015-11-10 16:53:46 +00:00
|
|
|
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"
|
2020-10-05 17:38:34 +00:00
|
|
|
) > "$HOME/.ssh/git-annex-shell.$$"
|
|
|
|
chmod +x "$HOME/.ssh/git-annex-shell.$$"
|
|
|
|
mv -f "$HOME/.ssh/git-annex-shell.$$" "$HOME/.ssh/git-annex-shell"
|
2015-11-10 16:53:46 +00:00
|
|
|
fi
|
2015-04-20 17:15:01 +00:00
|
|
|
fi
|
2012-10-29 18:40:28 +00:00
|
|
|
|
2015-11-10 16:53:46 +00:00
|
|
|
# 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' \"\$@\""
|
2020-10-05 17:38:34 +00:00
|
|
|
) > "$HOME/.ssh/git-annex-wrapper.$$"
|
|
|
|
chmod +x "$HOME/.ssh/git-annex-wrapper.$$"
|
|
|
|
mv -f "$HOME/.ssh/git-annex-wrapper.$$" "$HOME/.ssh/git-annex-wrapper"
|
2015-11-10 16:53:46 +00:00
|
|
|
fi
|
2015-11-10 15:42:06 +00:00
|
|
|
fi
|
2014-04-20 22:38:59 +00:00
|
|
|
fi
|
|
|
|
|
2018-04-25 21:58:00 +00:00
|
|
|
# Used by git-annex assistant to further install itself.
|
|
|
|
GIT_ANNEX_APP_BASE="$base"
|
|
|
|
export GIT_ANNEX_APP_BASE
|
|
|
|
|
2017-02-11 09:38:49 +00:00
|
|
|
# Put our binaries first, to avoid issues with out of date or incompatible
|
2016-02-19 20:19:19 +00:00
|
|
|
# system binaries. Extra binaries come after system path.
|
2012-11-27 21:05:29 +00:00
|
|
|
ORIG_PATH="$PATH"
|
|
|
|
export ORIG_PATH
|
2016-02-19 20:19:19 +00:00
|
|
|
PATH="$base/bin:$PATH:$base/extra"
|
2012-09-28 23:08:13 +00:00
|
|
|
export PATH
|
|
|
|
|
2015-08-04 20:08:19 +00:00
|
|
|
# These env vars are used by the shim wrapper around each binary.
|
2015-05-26 19:38:44 +00:00
|
|
|
for lib in $(cat "$base/libdirs"); do
|
2013-12-16 05:51:19 +00:00
|
|
|
GIT_ANNEX_LD_LIBRARY_PATH="$base/$lib:$GIT_ANNEX_LD_LIBRARY_PATH"
|
2012-09-28 23:08:13 +00:00
|
|
|
done
|
2013-12-16 05:51:19 +00:00
|
|
|
export GIT_ANNEX_LD_LIBRARY_PATH
|
2015-02-16 23:36:26 +00:00
|
|
|
GIT_ANNEX_DIR="$base"
|
|
|
|
export GIT_ANNEX_DIR
|
2013-12-16 05:51:19 +00:00
|
|
|
|
|
|
|
ORIG_GCONV_PATH="$GCONV_PATH"
|
|
|
|
export ORIG_GCONV_PATH
|
2015-05-26 19:38:44 +00:00
|
|
|
GCONV_PATH="$base/$(cat "$base/gconvdir")"
|
2013-12-16 05:51:19 +00:00
|
|
|
export GCONV_PATH
|
2012-09-28 23:08:13 +00:00
|
|
|
|
2012-11-27 21:05:29 +00:00
|
|
|
ORIG_GIT_EXEC_PATH="$GIT_EXEC_PATH"
|
|
|
|
export ORIG_GIT_EXEC_PATH
|
2015-05-26 19:38:44 +00:00
|
|
|
GIT_EXEC_PATH="$base/git-core"
|
2012-09-28 23:08:13 +00:00
|
|
|
export GIT_EXEC_PATH
|
|
|
|
|
2012-12-13 16:27:32 +00:00
|
|
|
ORIG_GIT_TEMPLATE_DIR="$GIT_TEMPLATE_DIR"
|
|
|
|
export ORIG_GIT_TEMPLATE_DIR
|
|
|
|
GIT_TEMPLATE_DIR="$base/templates"
|
|
|
|
export GIT_TEMPLATE_DIR
|
|
|
|
|
2013-12-15 20:27:46 +00:00
|
|
|
ORIG_MANPATH="$MANPATH"
|
|
|
|
export ORIG_MANPATH
|
|
|
|
MANPATH="$base/usr/share/man:$MANPATH"
|
|
|
|
export MANPATH
|
|
|
|
|
2018-07-10 16:13:14 +00:00
|
|
|
# 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
|
|
|
|
|
2016-10-04 20:37:43 +00:00
|
|
|
# Avoid using system locales, which may interact badly with bundled libc.
|
2020-08-03 17:43:21 +00:00
|
|
|
# (But if LOCPATH is set, don't override it.
|
2016-10-04 20:37:43 +00:00
|
|
|
ORIG_LOCPATH="$LOCPATH"
|
|
|
|
export ORIG_LOCPATH
|
runshell: Use system locales when built with GIT_ANNEX_PACKAGE_INSTALL set
This is to work around https://github.com/datalad/datalad/issues/2769
which I don't know how to reproduce outside that environment, nor do I
understand the root cause of. For some time, Neurodebian has been working
around it by building its standalone debs with a patch that disables use
of the locales bundled with the standalone build, letting the system
locales be used.
Using the system locales is asking for trouble if there's
significant version skew between the system and bundled glibc, and
possibly also if the architeciture is different, or whatever. That's why
git-annex bundles and uses its own locales, because numerous users
reported real problems with using the system locales.
... However, in the specific case of the Neurodebian standalone debs,
the deb is built on a system very like the one it's targeted to be
installed on. Or well, so they assure me, although doc/install/Ubuntu.mdwn
also promotes those for use across all versions of Ubuntu, and the deb
is built avoiding xz so it will work with old versions of dpkg, so I wonder
how true it is. It does seem that, at least currently, there is no bad
version skew in the locales of the systems the deb is used on, since
it's already been using the system locales for some time.
Anyway, since the Neurodebian build already is setting
GIT_ANNEX_PACKAGE_INSTALL=1 in runshell, I made runshell use system
locales when that's set. This is a small scope creep for
GIT_ANNEX_PACKAGE_INSTALL, but it's not documented and AFAIK only used
for the Neurodebian build, so that seems ok. This will let them stop
carrying their patch for this forward.
This work is supported by the NIH-funded NICEMAN (ReproNim TR&D3) project.
2018-10-13 19:04:02 +00:00
|
|
|
if [ -z "${LOCPATH+set}" ] && [ -z "$GIT_ANNEX_PACKAGE_INSTALL" ]; then
|
include buildid in LOCPATH
This avoids the possibility that the bundle could be updated in place,
leading to LOCPATH existing but containing locales for the old version,
which needed to be tested for with code that was not race-free.
LOCPATH/buildid is still written and checked when cleaning up stale caches.
That is not actually necessary, except old versions of the standalone
bundle expect to see it, and this prevents them cleaning up the locale
cache of a new version. And still checking it prevents the new version
cleaning up the locale cache of the old version while the old version is
still in use.
Added explicit tests before creating LOCPATH and the base and buildid files.
The buildid file no longer needs to be updated every time, because it's
stable for the given LOCPATH directory.
And the base file actually did not need to be updated every time,
because the LOCPATH is derived from base, so if the bundle is moved
elsewhere, a different LOCPATH will be used.
Transitioning to this will mean that two git-annex builds that otherwise
have the same buildid -- the same git-annex md5sum -- will use different
LOCPATH values, but that's handled fine by the cache cleanup code, so at
most it will mean one extra generation of the locale files.
2020-10-05 17:53:43 +00:00
|
|
|
LOCPATH="$HOME/.cache/git-annex/locales/$(cat "$base/buildid")_$(echo "$base" | tr / _ )"
|
2020-03-04 17:04:56 +00:00
|
|
|
# try to generate a short version, if md5sum is available
|
|
|
|
locpathmd5=$( (echo "$LOCPATH" | md5sum | cut -d ' ' -f 1 2>/dev/null) || true)
|
|
|
|
if [ -n "$locpathmd5" ]; then
|
|
|
|
LOCPATH="$HOME/.cache/git-annex/locales/$locpathmd5"
|
|
|
|
fi
|
2018-08-20 16:20:54 +00:00
|
|
|
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)
|
2018-10-10 19:28:27 +00:00
|
|
|
if [ ! -d "$cachebase" ] || ! cmp "$localecache/buildid" "$cachebase/buildid" >/dev/null 2>&1 ; then
|
2020-10-05 16:44:40 +00:00
|
|
|
rm -rf "$localecache" >/dev/null 2>&1 || true
|
2018-08-20 16:20:54 +00:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
include buildid in LOCPATH
This avoids the possibility that the bundle could be updated in place,
leading to LOCPATH existing but containing locales for the old version,
which needed to be tested for with code that was not race-free.
LOCPATH/buildid is still written and checked when cleaning up stale caches.
That is not actually necessary, except old versions of the standalone
bundle expect to see it, and this prevents them cleaning up the locale
cache of a new version. And still checking it prevents the new version
cleaning up the locale cache of the old version while the old version is
still in use.
Added explicit tests before creating LOCPATH and the base and buildid files.
The buildid file no longer needs to be updated every time, because it's
stable for the given LOCPATH directory.
And the base file actually did not need to be updated every time,
because the LOCPATH is derived from base, so if the bundle is moved
elsewhere, a different LOCPATH will be used.
Transitioning to this will mean that two git-annex builds that otherwise
have the same buildid -- the same git-annex md5sum -- will use different
LOCPATH values, but that's handled fine by the cache cleanup code, so at
most it will mean one extra generation of the locale files.
2020-10-05 17:53:43 +00:00
|
|
|
if [ ! -d "$LOCPATH" ]; then
|
|
|
|
if ! mkdir -p "$LOCPATH"; then
|
|
|
|
echo "Unable to write to $LOCPATH; can't continue!" >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ ! -e "$LOCPATH/base" ]; then
|
|
|
|
echo "$base" > "$LOCPATH/base.$$"
|
|
|
|
mv -f "$LOCPATH/base.$$" "$LOCPATH/base"
|
2018-07-10 16:13:14 +00:00
|
|
|
fi
|
include buildid in LOCPATH
This avoids the possibility that the bundle could be updated in place,
leading to LOCPATH existing but containing locales for the old version,
which needed to be tested for with code that was not race-free.
LOCPATH/buildid is still written and checked when cleaning up stale caches.
That is not actually necessary, except old versions of the standalone
bundle expect to see it, and this prevents them cleaning up the locale
cache of a new version. And still checking it prevents the new version
cleaning up the locale cache of the old version while the old version is
still in use.
Added explicit tests before creating LOCPATH and the base and buildid files.
The buildid file no longer needs to be updated every time, because it's
stable for the given LOCPATH directory.
And the base file actually did not need to be updated every time,
because the LOCPATH is derived from base, so if the bundle is moved
elsewhere, a different LOCPATH will be used.
Transitioning to this will mean that two git-annex builds that otherwise
have the same buildid -- the same git-annex md5sum -- will use different
LOCPATH values, but that's handled fine by the cache cleanup code, so at
most it will mean one extra generation of the locale files.
2020-10-05 17:53:43 +00:00
|
|
|
# Not using cp to avoid using the one bundled with git-annex
|
|
|
|
# before the environment is set up to run it.
|
|
|
|
if [ ! -e "$LOCPATH/buildid" ]; then
|
|
|
|
cat < "$base/buildid" > "$LOCPATH/buildid.$$"
|
|
|
|
mv -f "$LOCPATH/buildid.$$" "$LOCPATH/buildid"
|
2018-08-20 16:20:54 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
# 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
|
2020-10-05 17:37:00 +00:00
|
|
|
if [ -n "$localeenv" ] && [ "$localeenv" != "$lastlocaleenv" ]; then
|
2018-08-20 16:20:54 +00:00
|
|
|
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"
|
2020-10-05 17:42:43 +00:00
|
|
|
# In a race, LOCPATH may get created by another process,
|
|
|
|
# in which cache the mv above would put it here.
|
|
|
|
rm -rf "$LOCPATH/$localeenv/$localeenv.new.$$"
|
2018-08-20 16:20:54 +00:00
|
|
|
) >/dev/null 2>/dev/null || true
|
|
|
|
fi
|
2016-10-04 20:37:43 +00:00
|
|
|
fi
|
|
|
|
fi
|
2018-08-20 16:20:54 +00:00
|
|
|
done
|
|
|
|
fi
|
2016-10-04 20:37:43 +00:00
|
|
|
|
2018-05-05 12:55:50 +00:00
|
|
|
useproot=""
|
2018-04-25 17:47:43 +00:00
|
|
|
case "$os" in
|
|
|
|
# Make this bundle work well on Android.
|
|
|
|
Android)
|
|
|
|
if [ -e "$base/git" ]; then
|
2019-05-23 17:06:20 +00:00
|
|
|
echo "Running on Android.. Tuning for optimal behavior." >&2
|
2018-04-25 17:47:43 +00:00
|
|
|
# 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
|
2018-10-13 16:08:27 +00:00
|
|
|
# Use termux's uname, which knows it's on android,
|
|
|
|
# not the bundled one.
|
|
|
|
rm -f bin/uname
|
2018-10-11 17:22:02 +00:00
|
|
|
# Fix shell scripts to work when run inside proot.
|
|
|
|
termux-fix-shebang bin/* runshell git-annex git-annex-shell git-annex-webapp
|
2018-04-25 17:47:43 +00:00
|
|
|
cd "$orig"
|
|
|
|
# Save the poor Android user the typing.
|
2019-05-23 17:06:20 +00:00
|
|
|
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."
|
2018-04-25 17:47:43 +00:00
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
2018-05-05 12:55:50 +00:00
|
|
|
# Work around Android 8's seccomp filtering of some crucial
|
|
|
|
# system calls, using termux's version of proot.
|
|
|
|
useproot=1
|
|
|
|
|
2018-04-25 17:47:43 +00:00
|
|
|
# Store ssh connection caching sockets outside of sdcard.
|
2020-01-23 16:35:46 +00:00
|
|
|
GIT_ANNEX_SSH_SOCKET_DIR="$TMPDIR"
|
|
|
|
export GIT_ANNEX_SSH_SOCKET_DIR
|
2018-04-25 17:47:43 +00:00
|
|
|
|
|
|
|
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
|
2012-11-27 21:05:29 +00:00
|
|
|
|
2012-09-28 23:08:13 +00:00
|
|
|
if [ "$1" ]; then
|
|
|
|
cmd="$1"
|
|
|
|
shift 1
|
2018-05-05 12:55:50 +00:00
|
|
|
else
|
|
|
|
cmd=sh
|
|
|
|
fi
|
|
|
|
|
2020-08-03 18:34:15 +00:00
|
|
|
LD_HWCAP_MASK=
|
|
|
|
export LD_HWCAP_MASK
|
|
|
|
|
2020-07-24 18:46:50 +00:00
|
|
|
if [ -n "${orig_IFS}" ]; then
|
|
|
|
IFS="${orig_IFS}"
|
|
|
|
export IFS
|
|
|
|
fi
|
|
|
|
|
2018-05-05 12:55:50 +00:00
|
|
|
if [ -z "$tbase" ]; then
|
|
|
|
if [ "$useproot" ]; then
|
|
|
|
exec proot "$cmd" "$@"
|
|
|
|
else
|
2015-08-04 20:08:19 +00:00
|
|
|
exec "$cmd" "$@"
|
2018-05-05 12:55:50 +00:00
|
|
|
fi
|
|
|
|
else
|
|
|
|
# allow EXIT trap to cleanup
|
|
|
|
if [ "$useproot" ]; then
|
|
|
|
proot "$cmd" "$@"
|
2015-08-04 20:08:19 +00:00
|
|
|
else
|
|
|
|
"$cmd" "$@"
|
|
|
|
fi
|
2012-09-28 23:08:13 +00:00
|
|
|
fi
|