Skip to content

Commit

Permalink
Fix dsocks support
Browse files Browse the repository at this point in the history
  • Loading branch information
zjx20 committed Aug 30, 2022
1 parent 8384998 commit 5e5ca19
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 30 deletions.
23 changes: 14 additions & 9 deletions socksproxyenv.sample
Original file line number Diff line number Diff line change
Expand Up @@ -45,29 +45,34 @@ LOAD_SUPPORT mvn
# For example, to export FTP_PROXY:
# EXPORT_ENV FTP_PROXY "http://${SOCKS_CLI_HTTP_PROXY}"

EXPORT_ENV FOO "this is an example of EXPORT_ENV and should be removed!"
# EXPORT_ENV FOO "this is an example of EXPORT_ENV!"


# However, not all program has built-in proxy support. To settle these
# situations, dsocks (https://github.com/zjx20/dsocks) has been integrated
# into socks-cli.
#
# *PLEASE NOTICE* that dsocks doesn't work well with system binaries on
# macOS 10.11+ because of the SIP feature (a.k.a. System Integrity Protection).
# *PLEASE NOTICE* that dsocks doesn't work for system binaries (e.g. /bin/*,
# /usr/bin/*) on macOS 10.11+ because of the SIP (System Integrity Protection).
# But it should still work with commands installed by package management tools
# such as HomeBrew.

# Uncomment the line "LOAD_SUPPORT dsocks" to enable the dsocks support.
# "git" and "gcc" will be needed to bootstrap dsocks.

# LOAD_SUPPORT dsocks

# And then use the SOCKSIFY DSL to define which command to be socksified.
# For example:
#
# Uncomment any SOCKSIFY line to give a try:
#
# # socksify the curl command
# SOCKSIFY curl
# # socksify the python command and use "/usr/bin/env python" to run python
# SOCKSIFY python /usr/bin/env python
#
# After socksifying the "python" command, for example, you can run the
# following code snippet to verify it:
# # specifying "/usr/bin/env python" as the entrypoint of the socksified cmd.
# SOCKSIFY python3 /usr/bin/env python3
#
# Assume that you had socksified the "python3" command, you can check your
# external ip by running:
#
# python -c "import urllib2;print(urllib2.urlopen('http://fb.com/').read())"
# python3 -c "import urllib.request as r;print(r.urlopen('https://ipinfo.io/').read().decode('utf-8'))"
65 changes: 44 additions & 21 deletions supports/dsocks
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
#!/bin/bash
# The shebang is just a hint for editors.

function _socks_cli_clean_dsocks_tmp() {
local tmp_path="${SOCKS_CLI_DIR}/tmp/"
# First pass: remove command shadows if the shell has been dead.
find "${tmp_path}" -name "_shell_pid" -print0 |
while IFS= read -r -d '' file; do
pid="$(tr -d '\n\r' < "${file}")"
if [ "${pid}" = "$$" ]; then
# Ignore the current shell
continue
fi
if ! pgrep -F "${file}" > /dev/null; then
find "$(dirname "${file}")" -type f -delete
fi
done

# Second pass: remove empty directories recursively.
find "${tmp_path}" -empty -type d -delete
}

function socks_cli_activate_dsocks() {
_socks_cli_dsocks_lib="${SOCKS_CLI_DIR}/dsocks/libdsocks.so"
"${SOCKS_CLI_DIR}/sh/bootstrap-dsocks.sh"
Expand All @@ -10,6 +29,8 @@ function socks_cli_activate_dsocks() {
return 1
fi

_socks_cli_clean_dsocks_tmp

# Create a dedicated temporary folder for each shell process.
# Since the maximum pid number in unix-like OS is typically
# not greater than 999999, we can distribute the temporary
Expand All @@ -21,7 +42,9 @@ function socks_cli_activate_dsocks() {
local name=$((shell_pid%100))
local tmp_path="${SOCKS_CLI_DIR}/tmp/${level_one}/${level_two}/${name}"
mkdir -p "${tmp_path}"
[ -n "${tmp_path}" ] && rm -f "${tmp_path}/*"
# Remove existing command shadows
[ -n "${tmp_path}" ] && find "${tmp_path}/" -type f -delete
echo "${shell_pid}" > "${tmp_path}/_shell_pid"

local preappend="${tmp_path}"
if [ -n "${PATH}" ]; then
Expand All @@ -40,18 +63,6 @@ function socks_cli_deactivate_dsocks() {
unset _socks_cli_socksify
}

function _sed_escape() {
echo "$1" | sed -e 's/\\/\\\\/g; s/\//\\\//g; s/&/\\\&/g'
}
export -f _sed_escape > /dev/null

function socks_cli_replace() {
local search=$(_sed_escape "$2")
local replace=$(_sed_escape "$3")
echo "$1" | sed "s/${search}/${replace}/g"
}
export -f socks_cli_replace > /dev/null

function SOCKSIFY() {
if [ "${_socks_cli_socksify}" != "1" ]; then
return 1
Expand All @@ -63,12 +74,24 @@ function SOCKSIFY() {

local hook_command="$1"
local start_command="${@:2}"
local cmd_path="${_socks_cli_socksify_tmp_path}/${hook_command}"
cat <<-EOF > "${cmd_path}"
#!/bin/bash
# maintain the PATH env to avoid endless loop
export PATH="\$(socks_cli_replace "\$PATH" "${_socks_cli_socksify_path_preappend}" "")"
"${SOCKS_CLI_DIR}/dsocks/socksify" ${start_command} "\$@"
EOF
chmod +x "${cmd_path}"
if [ -z "$start_command" ]; then
start_command="${hook_command}"
fi
local cmd_shadow="${_socks_cli_socksify_tmp_path}/${hook_command}"
cat <<-EOF > "${cmd_shadow}"
#!/bin/bash
function _sed_escape() {
echo "\$1" | sed -e 's/\\\\/\\\\\\\\/g; s/\\//\\\\\\//g; s/&/\\\\\\&/g'
}
function socks_cli_replace() {
local search=\$(_sed_escape "\$2")
local replace=\$(_sed_escape "\$3")
echo "\$1" | sed "s/\${search}/\${replace}/g"
}
# remove the current folder from the PATH,
# to avoid recursively invoking this script.
export PATH="\$(socks_cli_replace "\$PATH" "${_socks_cli_socksify_path_preappend}" "")"
"${SOCKS_CLI_DIR}/dsocks/socksify" ${start_command} "\$@"
EOF
chmod +x "${cmd_shadow}"
}

0 comments on commit 5e5ca19

Please sign in to comment.