diff --git a/bash-zsh.sh b/bash-zsh.sh index 3f3a6e9..f143fa3 100644 --- a/bash-zsh.sh +++ b/bash-zsh.sh @@ -1,7 +1,20 @@ #!/bin/bash +# macOS does not come with readlink or realpath, so we need to take a portable substitute +source "./util/realpath.sh" -BASHRC=`readlink -f $HOME/.bashrc` -ZSHRC=`readlink -f $HOME/.zshrc` +case $os in + "Linux") + BASHRC=`readlink -f $HOME/.bashrc` + ZSHRC=`readlink -f $HOME/.zshrc` + ;; + "Darwin") + BASHRC=`realpath $HOME/.bashrc` + ZSHRC=`realpath $HOME/.zshrc` + ;; + *) echo "Operating system not supported. Exiting." + exit 1 + ;; +esac which bash &> /dev/null first="$?" diff --git a/install b/install index 6624496..6053004 100755 --- a/install +++ b/install @@ -22,7 +22,7 @@ echo "Press any key to continue, or Ctrl+C to break." read mkdir -p $TARGET_DIR -cp * $TARGET_DIR +cp -r * $TARGET_DIR # add to path mkdir -p $HOME/.local/bin diff --git a/linux_functions.sh b/linux_functions.sh new file mode 100644 index 0000000..778f0c6 --- /dev/null +++ b/linux_functions.sh @@ -0,0 +1,86 @@ +#!/bin/bash +# +# If you have found some issues, or some feature request : +# Raise them here : https://github.com/himanshub16/ProxyMan/issues +# Author : Himanshu Shekhar (@himanshub16) +# + +# This is the script that provides main script functions for Linux. + +function _do_it_for_selection() { + local what_to_do="$1" + for t in "${targets[@]}" + do + case "$t" in + # THIS stmt WILL CAUSE INFINITE RECURSION. DO NOT USE THIS. + # COMMENTED FOR WARNING + # 1) _do_it_for_all "$what_to_do" + # ;; + 2) bash "bash-zsh.sh" "$what_to_do" + ;; + 3) sudo -E bash "environment.sh" "$what_to_do" + ;; + 4) sudo -E bash "apt.sh" "$what_to_do" + sudo -E bash "dnf.sh" "$what_to_do" + ;; + 5) bash "gsettings.sh" "$what_to_do" + bash "kde5.sh" "$what_to_do" + ;; + 6) bash "npm.sh" "$what_to_do" + ;; + 7) bash "dropbox.sh" "$what_to_do" + ;; + 8) bash "git.sh" "$what_to_do" + ;; + 9) sudo -E bash "docker.sh" "$what_to_do" + ;; + *) ;; + esac + done +} + +function _do_it_for_all() { + # Argument + # $1 : what to do (set/unset/list) + + local what_to_do="$1" + if [[ -z "$targets" || "$targets" = "1" ]]; then + bash "bash-zsh.sh" "$what_to_do" + # avoiding /etc/environment in all because it requires logout after unset + # bashrc / zshrc is sufficient, and sudo -E might suffice + if [[ "$what_to_do" = "list" ]]; then + sudo -E bash "environment.sh" "$what_to_do" + fi + bash "gsettings.sh" "$what_to_do" + bash "kde5.sh" "$what_to_do" + bash "npm.sh" "$what_to_do" + bash "dropbox.sh" "$what_to_do" + bash "git.sh" "$what_to_do" + + # isn't required, but still checked to avoid sudo in main all the time + SUDO_CMDS="apt dnf docker" + for cmd in $SUDO_CMDS; do + command -v $cmd > /dev/null && sudo -E bash "${cmd}.sh" "$what_to_do" || : + done + else + _do_it_for_selection "$what_to_do" + fi +} + +function prompt_for_proxy_targets() { + echo "${bold}${blue} Select targets to modify ${normal}" + + echo "|${bold}${red} 1 ${normal}| All of them ... Don't bother me" + echo "|${bold}${red} 2 ${normal}| Terminal / bash / zsh (current user) " + echo "|${bold}${red} 3 ${normal}| /etc/environment" + echo "|${bold}${red} 4 ${normal}| apt/dnf (Package manager)" + echo "|${bold}${red} 5 ${normal}| Desktop settings (GNOME/Ubuntu/KDE)" + echo "|${bold}${red} 6 ${normal}| npm & yarn" + echo "|${bold}${red} 7 ${normal}| Dropbox" + echo "|${bold}${red} 8 ${normal}| Git" + echo "|${bold}${red} 9 ${normal}| Docker" + echo + echo "Separate multiple choices with space" + echo -n "${bold} ? ${normal}" ; read targets + export targets=(`echo ${targets}`) +} \ No newline at end of file diff --git a/macos_functions.sh b/macos_functions.sh new file mode 100644 index 0000000..7a345ef --- /dev/null +++ b/macos_functions.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# +# If you have found some issues, or some feature request : +# Raise them here : https://github.com/himanshub16/ProxyMan/issues +# Author : Benjamin Gericke (@deg0nz) +# + +# This is the script that provides main script functions for macOS. + +function _do_it_for_selection() { + local what_to_do="$1" + for t in ${targets[@]} + do + case "$t" in + # THIS stmt WILL CAUSE INFINITE RECURSION. DO NOT USE THIS. + # COMMENTED FOR WARNING + # 1) _do_it_for_all "$what_to_do" + # ;; + 2) bash "networksetup.sh" "$what_to_do" + ;; + 3) bash "bash-zsh.sh" "$what_to_do" + ;; + 4) bash "npm.sh" "$what_to_do" + ;; + 5) bash "git.sh" "$what_to_do" + ;; + *) ;; + esac + done +} + +function _do_it_for_all() { + # Argument + # $1 : what to do (set/unset/list) + + local what_to_do="$1" + if [[ -z "$targets" || "$targets" = "1" ]]; then + + bash "bash-zsh.sh" "$what_to_do" + bash "networksetup.sh" "$what_to_do" + bash "npm.sh" "$what_to_do" + bash "git.sh" "$what_to_do" + + else + _do_it_for_selection "$what_to_do" + fi +} + +function prompt_for_proxy_targets() { + echo "${bold}${blue} Select targets to modify ${normal}" + + echo "|${bold}${red} 1 ${normal}| All of them ... Don't bother me" + echo "|${bold}${red} 2 ${normal}| System-wide settings (networksetup)" + echo "|${bold}${red} 3 ${normal}| Terminal / bash / zsh (current user)" + echo "|${bold}${red} 4 ${normal}| npm & yarn" + echo "|${bold}${red} 5 ${normal}| Git" + echo + echo "Separate multiple choices with space" + echo -n "${bold} ? ${normal}" ; read targets + export targets=(`echo ${targets}`) +} \ No newline at end of file diff --git a/main.sh b/main.sh index 02184a3..1cf2f16 100755 --- a/main.sh +++ b/main.sh @@ -11,62 +11,16 @@ source "./variables.sh" source "./configs.sh" - -function _do_it_for_all() { - # Argument - # $1 : what to do (set/unset/list) - - local what_to_do="$1" - if [[ -z "$targets" || "$targets" = "1" ]]; then - bash "bash-zsh.sh" "$what_to_do" - # avoiding /etc/environment in all because it requires logout after unset - # bashrc / zshrc is sufficient, and sudo -E might suffice - if [[ "$what_to_do" = "list" ]]; then - sudo -E bash "environment.sh" "$what_to_do" - fi - bash "gsettings.sh" "$what_to_do" - bash "kde5.sh" "$what_to_do" - bash "npm.sh" "$what_to_do" - bash "dropbox.sh" "$what_to_do" - bash "git.sh" "$what_to_do" - - # isn't required, but still checked to avoid sudo in main all the time - SUDO_CMDS="apt dnf docker" - for cmd in $SUDO_CMDS; do - command -v $cmd > /dev/null && sudo -E bash "${cmd}.sh" "$what_to_do" || : - done - else - for t in "${targets[@]}" - do - case "$t" in - # THIS stmt WILL CAUSE INFINITE RECURSION. DO NOT USE THIS. - # COMMENTED FOR WARNING - # 1) _do_it_for_all "$what_to_do" - # ;; - 2) bash "bash-zsh.sh" "$what_to_do" - ;; - 3) sudo -E bash "environment.sh" "$what_to_do" - ;; - 4) sudo -E bash "apt.sh" "$what_to_do" - sudo -E bash "dnf.sh" "$what_to_do" - ;; - 5) bash "gsettings.sh" "$what_to_do" - bash "kde5.sh" "$what_to_do" - ;; - 6) bash "npm.sh" "$what_to_do" - ;; - 7) bash "dropbox.sh" "$what_to_do" - ;; - 8) bash "git.sh" "$what_to_do" - ;; - 9) sudo -E bash "docker.sh" "$what_to_do" - ;; - *) ;; - esac - done - - fi -} +# Load main functions for current operating system +case $os in + "Linux") source "./linux_functions.sh" + ;; + "Darwin") source "./macos_functions.sh" + ;; + *) echo "Operating system not supported. Exiting." + exit 1 + ;; +esac function _dump_it_all() { echo "HTTP > $http_host $http_port" @@ -140,24 +94,6 @@ function prompt_for_proxy_values() { echo } -function prompt_for_proxy_targets() { - echo "${bold}${blue} Select targets to modify ${normal}" - - echo "|${bold}${red} 1 ${normal}| All of them ... Don't bother me" - echo "|${bold}${red} 2 ${normal}| Terminal / bash / zsh (current user) " - echo "|${bold}${red} 3 ${normal}| /etc/environment" - echo "|${bold}${red} 4 ${normal}| apt/dnf (Package manager)" - echo "|${bold}${red} 5 ${normal}| Desktop settings (GNOME/Ubuntu/KDE)" - echo "|${bold}${red} 6 ${normal}| npm & yarn" - echo "|${bold}${red} 7 ${normal}| Dropbox" - echo "|${bold}${red} 8 ${normal}| Git" - echo "|${bold}${red} 9 ${normal}| Docker" - echo - echo "Separate multiple choices with space" - echo -ne "\e[5m ? \e[0m" ; read targets - export targets=(`echo ${targets}`) -} - function main() { case "$1" in "configs" ) list_configs diff --git a/networksetup.sh b/networksetup.sh new file mode 100644 index 0000000..90d1e15 --- /dev/null +++ b/networksetup.sh @@ -0,0 +1,117 @@ +#!/bin/bash +# +# If you have found some issues, or some feature request : +# Raise them here : https://github.com/himanshub16/ProxyMan/issues +# Author : Benjamin Gericke (@deg0nz) +# + +# This is the script that provides functions for macOS's networksetup tool. + +function _prompt_networkservices_targets() { + echo "${bold}${blue} Select network interfaces to modify ${normal}" + + echo "|${bold}${red} 1 ${normal}| All of them ... Don't bother me" + local IFS=$'\n' + local counter=2 + for line in $(networksetup -listallnetworkservices); do + # TODO: Handle disabled services + if [[ "$line" == "An asterisk (*) denotes that a network service is disabled." ]]; then + continue + fi + echo "|${bold}${red} ${counter} ${normal}| ${line} " + # We write the array from 0, although 1 is "all devices" + # loop for selected services must be adjusted + arraypos="(($counter-2))" + networkservices_array[$arraypos]="$line" + ((counter++)) + done + echo + echo "Separate multiple choices with space" + echo -n "${bold} ? ${normal}" ; read targets_networkservices + export targets_networkservices=(`echo ${targets_networkservices}`) +} + +function _set_proxy_for_networkservice() { + local networkservice="$1" + # Parameters: [-setwebproxy networkservice domain portnumber authenticated username password] + if [[ "$use_auth" = "y" ]]; then + networksetup -setwebproxy "$networkservice" "$http_host" "$http_port" on "$username" "$password" + networksetup -setsecurewebproxy "$networkservice" "$https_host" "$https_port" on "$username" "$password" + networksetup -setftpproxy "$networkservice" "$http_host" "$http_port" on "$username" "$password" + else + networksetup -setwebproxy "$networkservice" "$http_host" "$http_port" off + networksetup -setsecurewebproxy "$networkservice" "$https_host" "$https_port" off + networksetup -setftpproxy "$networkservice" "$http_host" "$http_port" off + fi + + networksetup -setproxybypassdomains "$networkservice" "$no_proxy" +} + +function _unset_proxy_for_networkservice() { + local networkservice="$1" + + networksetup -setwebproxystate "$networkservice" off + networksetup -setsecurewebproxystate "$networkservice" off + networksetup -setftpproxystate "$networkservice" off + networksetup -setproxyautodiscovery "$networkservice" off +} + +function list_proxy() { + # TODO + echo "Listing proxies for system-wide settings on macOS is not yet implemented." + echo "Please look into System Preferences -> Network -> -> Advanced -> Proxies for now." +} + +function unset_proxy() { + echo "Additional information for ${bold}unsetting${normal} system-wide proxy is needed." + + _prompt_networkservices_targets + + if [[ -z "$targets_networkservices" || "$targets_networkservices" = "1" ]]; then + # Unset for all services + local IFS=$'\n' + for networkservice in ${networkservices_array[*]}; do + _unset_proxy_for_networkservice "$networkservice" + done + else + # Unset for selection + for arrayindex in ${targets_networkservices[@]}; do + # We need to correct the index, because 1 is "all devices", so all the indexes are increased by 1 + corrected_index="(($arrayindex-2))" + _unset_proxy_for_networkservice "${networkservices_array[$corrected_index]}" + done + fi +} + +function set_proxy() { + echo "Additional information for ${bold}setting${normal} system-wide proxy is needed." + + _prompt_networkservices_targets + + if [[ -z "$targets_networkservices" || "$targets_networkservices" = "1" ]]; then + # Set for all services + local IFS=$'\n' + for networkservice in ${networkservices_array[*]}; do + _set_proxy_for_networkservice "$networkservice" + done + else + # Set for selection of services + for arrayindex in ${targets_networkservices[@]}; do + # We need to correct the index, because 1 is "all devices", so all the indexes are increased by 1 + corrected_index="(($arrayindex-2))" + _set_proxy_for_networkservice "${networkservices_array[$corrected_index]}" + done + fi +} + +what_to_do=$1 +case $what_to_do in + set) set_proxy + ;; + unset) unset_proxy + ;; + list) list_proxy + ;; + *) + ;; +esac \ No newline at end of file diff --git a/shellrc.sh b/shellrc.sh index 8cc1865..eff683b 100644 --- a/shellrc.sh +++ b/shellrc.sh @@ -25,14 +25,33 @@ unset_proxy() { if [ ! -e "$SHELLRC" ]; then return fi - # extra effort required to avoid removing custom environment variables set - # by the user for personal use - for proxytype in "http" "https" "ftp" "rsync" "no"; do - sed -i "/export ${proxytype}_proxy\=/d" "$SHELLRC" - done - for PROTOTYPE in "HTTP" "HTTPS" "FTP" "RSYNC" "NO"; do - sed -i "/export ${PROTOTYPE}_PROXY\=/d" "$SHELLRC" - done + + # macOS ships with BSD sed, which has different syntax from GNU sed + case $os in + "Linux") + # extra effort required to avoid removing custom environment variables set + # by the user for personal use + for proxytype in "http" "https" "ftp" "rsync" "no"; do + sed -i "/export ${proxytype}_proxy\=/d" "$SHELLRC" + done + for PROXYTYPE in "HTTP" "HTTPS" "FTP" "RSYNC" "NO"; do + sed -i "/export ${PROXYTYPE}_PROXY\=/d" "$SHELLRC" + done + ;; + "Darwin") + # extra effort required to avoid removing custom environment variables set + # by the user for personal use + for proxytype in "http" "https" "ftp" "rsync" "no"; do + sed -i "" "/export ${proxytype}_proxy\=/d" "$SHELLRC" + done + for PROXYTYPE in "HTTP" "HTTPS" "FTP" "RSYNC" "NO"; do + sed -i "" "/export ${PROXYTYPE}_PROXY\=/d" "$SHELLRC" + done + ;; + *) echo "Operating system not supported. Exiting." + exit 1 + ;; + esac } set_proxy() { diff --git a/util/realpath.sh b/util/realpath.sh new file mode 100644 index 0000000..9946cdf --- /dev/null +++ b/util/realpath.sh @@ -0,0 +1,71 @@ +#!/bin/sh +# Pure shell implementation of realpath +# Taken from https://github.com/mkropat/sh-realpath + +realpath() { + canonicalize_path "$(resolve_symlinks "$1")" +} + +resolve_symlinks() { + _resolve_symlinks "$1" +} + +_resolve_symlinks() { + _assert_no_path_cycles "$@" || return + + local dir_context path + path=$(readlink -- "$1") + if [ $? -eq 0 ]; then + dir_context=$(dirname -- "$1") + _resolve_symlinks "$(_prepend_dir_context_if_necessary "$dir_context" "$path")" "$@" + else + printf '%s\n' "$1" + fi +} + +_prepend_dir_context_if_necessary() { + if [ "$1" = . ]; then + printf '%s\n' "$2" + else + _prepend_path_if_relative "$1" "$2" + fi +} + +_prepend_path_if_relative() { + case "$2" in + /* ) printf '%s\n' "$2" ;; + * ) printf '%s\n' "$1/$2" ;; + esac +} + +_assert_no_path_cycles() { + local target path + + target=$1 + shift + + for path in "$@"; do + if [ "$path" = "$target" ]; then + return 1 + fi + done +} + +canonicalize_path() { + if [ -d "$1" ]; then + _canonicalize_dir_path "$1" + else + _canonicalize_file_path "$1" + fi +} + +_canonicalize_dir_path() { + (cd "$1" 2>/dev/null && pwd -P) +} + +_canonicalize_file_path() { + local dir file + dir=$(dirname -- "$1") + file=$(basename -- "$1") + (cd "$dir" 2>/dev/null && printf '%s/%s\n' "$(pwd -P)" "$file") +} diff --git a/variables.sh b/variables.sh index 25b451b..47b896d 100644 --- a/variables.sh +++ b/variables.sh @@ -36,6 +36,7 @@ fi export config_dir="$HOME/.config/proxyman" export default_config="default" export SHELLRC="$HOME/.bashrc" +export os=`uname` case "$SHELL" in "$(which bash)") SHELLRC="$HOME/.bashrc"