forked from admin/terminal_worse
223 lines
6.9 KiB
Bash
Executable File
223 lines
6.9 KiB
Bash
Executable File
#!/bin/sh
|
|
# termenv - independent native plugin environment for Terminal
|
|
# This is a POSIX sh environment, not a Linux userland. Packages are
|
|
# Terminal-compatible .deb files (scripts or iOS/Darwin arm64 binaries).
|
|
|
|
ROOT="${TERM_ROOT:-$HOME/Documents/.terminal}"
|
|
APPDIR="${APPDIR:-/Applications/Terminal.app}"
|
|
PROFILE="$ROOT/etc/profile"
|
|
SOURCES="$ROOT/etc/apt/sources.list"
|
|
|
|
usage() {
|
|
printf '%s\n' "Usage: termenv <command>"
|
|
printf '%s\n' ""
|
|
printf '%s\n' " init Create the independent prefix and the local apt repository"
|
|
printf '%s\n' " status Show prefix, PATH, apt/dpkg and installed packages"
|
|
printf '%s\n' " enter Print the command that activates the environment"
|
|
printf '%s\n' " run <cmd...> Run a command inside the environment"
|
|
printf '%s\n' " on Add activation to ~/Documents/.profile"
|
|
printf '%s\n' " off Remove activation from ~/Documents/.profile"
|
|
printf '%s\n' " selftest init + apt update + install the sample \"hello\" package"
|
|
printf '%s\n' " clean Remove apt caches and temporary files"
|
|
printf '%s\n' ""
|
|
printf '%s\n' "Environment:"
|
|
printf '%s\n' " TERM_ROOT=~/Documents/.terminal"
|
|
printf '%s\n' " PREFIX=$TERM_ROOT"
|
|
}
|
|
ensure_dirs() {
|
|
mkdir -p "$ROOT/bin" "$ROOT/sbin" "$ROOT/lib" "$ROOT/include" \
|
|
"$ROOT/share/man" "$ROOT/etc/apt" \
|
|
"$ROOT/var/lib/dpkg/info" "$ROOT/var/lib/apt/lists" \
|
|
"$ROOT/var/cache/apt/archives" "$ROOT/var/log" \
|
|
"$ROOT/tmp" "$ROOT/repo/pool" "$ROOT/home"
|
|
[ -f "$ROOT/var/lib/dpkg/status" ] || : > "$ROOT/var/lib/dpkg/status"
|
|
}
|
|
|
|
write_profile() {
|
|
if [ ! -f "$PROFILE" ]; then
|
|
cat > "$PROFILE" <<EOF
|
|
# Terminal plugin environment (generated by termenv init)
|
|
TERM_ROOT="\$HOME/Documents/.terminal"
|
|
export TERM_ROOT
|
|
PREFIX="\$TERM_ROOT"
|
|
export PREFIX
|
|
TERM_PLUGIN_ENV=1
|
|
export TERM_PLUGIN_ENV
|
|
PATH="\$TERM_ROOT/bin:\$TERM_ROOT/sbin:\$TERM_ROOT/usr/bin:\$PATH"
|
|
export PATH
|
|
LD_LIBRARY_PATH="\$TERM_ROOT/lib:\$TERM_ROOT/usr/lib:\$LD_LIBRARY_PATH"
|
|
export LD_LIBRARY_PATH
|
|
CPATH="\$TERM_ROOT/include:\$CPATH"
|
|
export CPATH
|
|
LIBRARY_PATH="\$TERM_ROOT/lib:\$TERM_ROOT/usr/lib:\$LIBRARY_PATH"
|
|
export LIBRARY_PATH
|
|
PKG_CONFIG_PATH="\$TERM_ROOT/lib/pkgconfig:\$PKG_CONFIG_PATH"
|
|
export PKG_CONFIG_PATH
|
|
MANPATH="\$TERM_ROOT/share/man:\$MANPATH"
|
|
export MANPATH
|
|
EOF
|
|
fi
|
|
}
|
|
|
|
write_sources() {
|
|
LOCAL_LINE="deb [trusted=yes] file://$ROOT/repo ./"
|
|
PROCURUS_LINE="deb [trusted=yes] https://repo.procurs.us/ ./"
|
|
HAVOC_LINE="deb [trusted=yes] https://repo.havoc.app/ ./"
|
|
if [ ! -f "$SOURCES" ]; then
|
|
{
|
|
printf '%s\n' "$LOCAL_LINE"
|
|
printf '%s\n' "$PROCURUS_LINE"
|
|
printf '%s\n' "$HAVOC_LINE"
|
|
} > "$SOURCES"
|
|
return
|
|
fi
|
|
TMP="$ROOT/tmp/sources.$$"
|
|
awk -v desired="$LOCAL_LINE" '
|
|
/^deb .*file:\/\/.*\/\.terminal\/repo/ { print desired; found=1; next }
|
|
{ print }
|
|
END { if (!found) print desired }
|
|
' "$SOURCES" > "$TMP"
|
|
mv "$TMP" "$SOURCES"
|
|
if ! grep -qF "https://repo.procurs.us/" "$SOURCES"; then
|
|
printf '%s\n' "$PROCURUS_LINE" >> "$SOURCES"
|
|
fi
|
|
if ! grep -qF "https://repo.havoc.app/" "$SOURCES"; then
|
|
printf '%s\n' "$HAVOC_LINE" >> "$SOURCES"
|
|
fi
|
|
}
|
|
|
|
make_sample() {
|
|
if grep -q '^Package: hello$' "$ROOT/repo/Packages" 2>/dev/null; then
|
|
return 0
|
|
fi
|
|
SAMPLE="$ROOT/share/termenv/samples/hello"
|
|
mkdir -p "$SAMPLE/bin"
|
|
cat > "$SAMPLE/bin/hello" << 'EOF'
|
|
#!/bin/sh
|
|
echo "Hello from the Terminal plugin environment."
|
|
echo "PREFIX=$PREFIX"
|
|
echo "TERM_ROOT=$TERM_ROOT"
|
|
if [ -d "$HOME/Documents/_sandbox" ]; then
|
|
echo "Sandbox escape: available (see $HOME/Documents/_sandbox)"
|
|
fi
|
|
EOF
|
|
chmod +x "$SAMPLE/bin/hello"
|
|
if [ -f "$APPDIR/bin/mkdeb" ]; then
|
|
sh "$APPDIR/bin/mkdeb" hello 1.0.0 "$SAMPLE" iphoneos-arm64
|
|
echo "termenv: mkdeb exit=$?"
|
|
fi
|
|
}
|
|
|
|
do_init() {
|
|
echo "termenv: creating directories..."
|
|
ensure_dirs
|
|
echo "termenv: writing profile/sources..."
|
|
write_profile
|
|
write_sources
|
|
[ -f "$ROOT/repo/Packages" ] || : > "$ROOT/repo/Packages"
|
|
echo "termenv: creating sample package..."
|
|
make_sample
|
|
echo "termenv: sample ready"
|
|
echo "Prefix: $ROOT"
|
|
echo "Profile: $PROFILE"
|
|
echo "Run: source \"$PROFILE\" (or: termenv on)"
|
|
}
|
|
|
|
do_status() {
|
|
ensure_dirs
|
|
echo "Terminal native plugin environment"
|
|
echo " prefix: $ROOT"
|
|
echo " profile: $PROFILE"
|
|
echo " apt: $APPDIR/bin/apt"
|
|
echo " dpkg: $APPDIR/bin/dpkg"
|
|
echo " sources: $SOURCES"
|
|
if [ -f "$SOURCES" ]; then
|
|
sed 's/^/ /' "$SOURCES"
|
|
fi
|
|
echo " packages:"
|
|
if [ -s "$ROOT/var/lib/dpkg/status" ]; then
|
|
awk '/^Package: /{printf " %s", substr($0,10)} /^Version: /{printf " %s", substr($0,10)} /^Status: /{status=substr($0,9)} /^$/{if(status ~ /installed/) print ""}' "$ROOT/var/lib/dpkg/status"
|
|
else
|
|
echo " (none)"
|
|
fi
|
|
echo " sandbox: $HOME/Documents/_sandbox"
|
|
}
|
|
|
|
do_run() {
|
|
if [ $# -eq 0 ]; then
|
|
echo "usage: termenv run <command...>" >&2
|
|
exit 2
|
|
fi
|
|
if [ -f "$PROFILE" ]; then
|
|
. "$PROFILE"
|
|
fi
|
|
"$@"
|
|
}
|
|
|
|
do_on() {
|
|
do_init
|
|
PROFILE_FILE="$HOME/Documents/.profile"
|
|
MARK_BEGIN="# >>> Terminal plugin environment >>>"
|
|
MARK_END="# <<< Terminal plugin environment <<<"
|
|
if grep -qF "$MARK_BEGIN" "$PROFILE_FILE" 2>/dev/null; then
|
|
echo "Activation already present in $PROFILE_FILE"
|
|
return 0
|
|
fi
|
|
{
|
|
echo "$MARK_BEGIN"
|
|
echo "source \"\$HOME/Documents/.terminal/etc/profile\""
|
|
echo "$MARK_END"
|
|
} >> "$PROFILE_FILE"
|
|
echo "Activation added to $PROFILE_FILE"
|
|
}
|
|
|
|
do_off() {
|
|
PROFILE_FILE="$HOME/Documents/.profile"
|
|
if [ ! -f "$PROFILE_FILE" ]; then
|
|
echo "No $PROFILE_FILE"
|
|
return 0
|
|
fi
|
|
TMP="$ROOT/tmp/profile.$$"
|
|
awk '
|
|
/# >>> Terminal plugin environment >>>/ {skip=1; next}
|
|
/# <<< Terminal plugin environment <<</ {skip=0; next}
|
|
!skip {print}
|
|
' "$PROFILE_FILE" > "$TMP"
|
|
mv "$TMP" "$PROFILE_FILE"
|
|
echo "Activation removed from $PROFILE_FILE"
|
|
}
|
|
|
|
do_clean() {
|
|
rm -rf "$ROOT/tmp"/*
|
|
rm -f "$ROOT/var/cache/apt/archives/"*.deb
|
|
echo "Cleaned caches"
|
|
}
|
|
|
|
do_selftest() {
|
|
do_init
|
|
. "$PROFILE"
|
|
echo "=== apt update ==="
|
|
APT_SKIP_REMOTE=1 sh "$APPDIR/bin/apt" update
|
|
echo "=== apt install hello ==="
|
|
sh "$APPDIR/bin/apt" install hello
|
|
echo "=== hello ==="
|
|
hello
|
|
echo "=== installed packages ==="
|
|
sh "$APPDIR/bin/apt" list --installed
|
|
echo "=== dpkg -l ==="
|
|
sh "$APPDIR/bin/dpkg" -l
|
|
}
|
|
|
|
case "${1:-}" in
|
|
init) do_init ;;
|
|
status) do_status ;;
|
|
enter) echo "source \"$PROFILE\"" ;;
|
|
run) shift; do_run "$@" ;;
|
|
on) do_on ;;
|
|
off) do_off ;;
|
|
clean) do_clean ;;
|
|
selftest) do_selftest ;;
|
|
""|-h|--help|help) usage ;;
|
|
*) usage; exit 2 ;;
|
|
esac
|