File: runshell

package info (click to toggle)
git-annex 8.20210223-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 68,764 kB
  • sloc: haskell: 70,359; javascript: 9,103; sh: 1,304; makefile: 212; perl: 136; ansic: 44
file content (274 lines) | stat: -rwxr-xr-x 8,498 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
#!/bin/sh
# Runs a shell command (or interactive shell) using the binaries and
# libraries bundled with this app.

# 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=

set -e

orig_IFS="${IFS}"
unset IFS

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

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.$$"
			mv -f "$HOME/.ssh/git-annex-shell.$$" "$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.$$"
			mv -f "$HOME/.ssh/git-annex-wrapper.$$" "$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.
ORIG_LOCPATH="$LOCPATH"
export ORIG_LOCPATH
if [ -z "${LOCPATH+set}" ] && [ -z "$GIT_ANNEX_PACKAGE_INSTALL" ]; then
	locpathbase="$(cat "$base/buildid")_$(echo "$base" | tr / _ )"
	# try to generate a short version, if md5sum is available
	locpathmd5=$( (echo "$locpathbase" | md5sum | cut -d ' ' -f 1 2>/dev/null) || true)
	if [ -n "$locpathmd5" ]; then
		locpathbase="$locpathmd5"
	fi
	LOCPATH="$HOME/.cache/git-annex/locales/$locpathbase"
	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" ] || [ "$(cat "$localecache/buildid" 2>/dev/null || true)" != "$(cat "$cachebase/buildid" 2>/dev/null || true)" ]; then
			rm -rf "$localecache" >/dev/null 2>&1 || true
		fi
	done
	
	if [ ! -d "$LOCPATH" ]; then
		if ! mkdir -p "$HOME/.cache/git-annex/locales"; then
			echo "Unable to write to $HOME/.cache/git-annex/locales; can't continue!" >&2
			exit 1
		fi
		locpathtmp="$HOME/.cache/git-annex/locales.tmp/$locpathbase.$$"
		if ! mkdir -p "$locpathtmp"; then
			echo "Unable to write to $locpathtmp; can't continue!" >&2
			exit 1
		fi
		echo "$base" > "$locpathtmp/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" > "$locpathtmp/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 [ -n "$localeenv" ] && [ "$localeenv" != "$lastlocaleenv" ]; then
				lastlocaleenv="$localeenv"
				if [ ! -d "$locpathtmp/$localeenv" ]; then
					if [ "${localeenv##[!.]*.}" = "utf8" ] || [ "${localeenv##[!.]*.}" = "UTF-8" ]; then
						(
							mkdir -p "$locpathtmp/$localeenv" &&
							# 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 "$locpathtmp/$localeenv"
						) >/dev/null 2>/dev/null || true
					fi
				fi
			fi
		done
		
		mv "$locpathtmp" "$LOCPATH"
		# In a race, LOCPATH may get created by another process,
		# in which cache the mv above would put it here.
		rm -rf "$LOCPATH/$locpathbase.$$"
	fi
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_SSH_SOCKET_DIR="$TMPDIR"
		export GIT_ANNEX_SSH_SOCKET_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

LD_HWCAP_MASK=
export LD_HWCAP_MASK

if [ -n "${orig_IFS}" ]; then
	IFS="${orig_IFS}"
	export IFS
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