#!/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. ORIG_LOCPATH="$LOCPATH" export ORIG_LOCPATH LOCPATH="$HOME/.cache/git-annex/locales/$(echo "$base" | tr / _ )" if ! mkdir -p "$LOCPATH" 2>/dev/null; then tlocpath=$(mktemp -d -p /tmp annexlocalesXXXXXXXXX 2>/dev/null || true) if [ -z "$tlocpath" ]; then tlocpath="/tmp/annexlocales.$$" fi LOCPATH="$tlocpath/locales/$(echo "$base" | tr / _ )" fi 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 ; then rm -rf "$localecache" 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 ; then rm -rf "$LOCPATH" fi mkdir -p "$LOCPATH" echo "$base" > "$LOCPATH/base" cp "$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 useproot="" case "$os" in # Make this bundle work well on Android. Android) if [ -e "$base/git" ]; then echo "Running on Android.. Adding git-annex to PATH for you, and 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 cd "$orig" # Save the poor Android user the typing. if ! [ -e "$HOME/.profile" ] || ! grep -q "$base" "$HOME/.profile"; then echo 'PATH=$PATH:'"$base" >> $HOME/.profile 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