SSH_CLIPBOARD_DIR="${SSH_CLIPBOARD_DIR:-$HOME/.cache}" SSH_CLIPBOARD_SOCKET="${SSH_CLIPBOARD_SOCKET:-$SSH_CLIPBOARD_DIR/ssh-clipboard.sock}" SSH_CLIPBOARD_PIDFILE="${SSH_CLIPBOARD_PIDFILE:-$SSH_CLIPBOARD_DIR/ssh-clipboard.pid}" SSH_CLIPBOARD_LOG="${SSH_CLIPBOARD_LOG:-$SSH_CLIPBOARD_DIR/ssh-clipboard.log}" # This path is created on the remote host. # Override it when the remote username differs from the local username. SSH_CLIPBOARD_REMOTE_SOCKET="/tmp/ssh-clipboard-client.sock" function clipboard_server_running { local pid if [ -n "${SSH_CLIPBOARD_REMOTE_SOCKET:-}" ] && [ -S "$SSH_CLIPBOARD_REMOTE_SOCKET" ]; then return 0 fi [[ -f "$SSH_CLIPBOARD_PIDFILE" ]] || return 1 read -r pid < "$SSH_CLIPBOARD_PIDFILE" [[ "$pid" =~ ^[0-9]+$ ]] || return 1 kill -0 "$pid" 2>/dev/null } function init_clipboard_server { if clipboard_server_running; then return 0 fi case "$OSTYPE" in darwin*) command -v socat >/dev/null 2>&1 || { echo "clipboard server: socat is not installed" >&2 echo "Install it with: brew install socat" >&2 return 1 } [[ -x /usr/bin/pbcopy ]] || { echo "clipboard server: /usr/bin/pbcopy was not found" >&2 return 1 } mkdir -p "$SSH_CLIPBOARD_DIR" chmod 700 "$SSH_CLIPBOARD_DIR" rm -f "$SSH_CLIPBOARD_SOCKET" "$SSH_CLIPBOARD_PIDFILE" ( umask 077 socat \ "UNIX-LISTEN:$SSH_CLIPBOARD_SOCKET,fork,mode=600" \ EXEC:/usr/bin/pbcopy \ >>"$SSH_CLIPBOARD_LOG" 2>&1 & echo "$!" > "$SSH_CLIPBOARD_PIDFILE" ) ;; cygwin*) echo "clipboard server: Cygwin support is not implemented" >&2 return 1 ;; *) echo "clipboard server: $OSTYPE is not supported" >&2 return 1 ;; esac } function stop_clipboard_server { local pid if clipboard_server_running; then read -r pid < "$SSH_CLIPBOARD_PIDFILE" kill "$pid" 2>/dev/null || true fi rm -f "$SSH_CLIPBOARD_SOCKET" "$SSH_CLIPBOARD_PIDFILE" } function clipboard_server_config { cat </dev/null 2>&1 || { echo "pbcopy: socat is required for the remote clipboard" >&2 return 1 } socat - "UNIX-CONNECT:$SSH_CLIPBOARD_REMOTE_SOCKET" return $? fi case "$OSTYPE" in darwin*) if [ -x /usr/bin/pbcopy ]; then /usr/bin/pbcopy else echo "pbcopy: /usr/bin/pbcopy was not found" >&2 return 1 fi ;; *) echo "pbcopy: no remote clipboard socket is available" >&2 return 1 ;; esac } function cleanup_ssh_clipboard { [ -n "${SSH_CONNECTION:-}" ] || return [ -S "$SSH_CLIPBOARD_REMOTE_SOCKET" ] || return rm -f -- "$SSH_CLIPBOARD_REMOTE_SOCKET" } if [ -z "${SSH_CONNECTION:-}" ] && init_clipboard_server; then alias ssh='sshc' fi if [ -n "${SSH_CONNECTION:-}" ]; then trap cleanup_ssh_clipboard EXIT HUP TERM fi