diff --git a/.gitignore b/.gitignore index d57cb1d..38db181 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ debian/debhelper-build-stamp debian/files debian/pulseaudio-tcp.substvars debian/pulseaudio-tcp +*.sw* diff --git a/pulseaudio-tcp b/pulseaudio-tcp index 3fbdb7c..de5cce3 100644 --- a/pulseaudio-tcp +++ b/pulseaudio-tcp @@ -22,16 +22,24 @@ usage() { cat >&2 < ~/.config/pulse/cookie ; then + debug "Using PulseAudio cookie value as passed on the command line ..." + return 0 + else + error "Decoding Base64 value of option --cookie failed." + return 1 + fi + elif _scp "$remote_user"@"$remote_ip":.config/pulse/cookie ~/.config/pulse/cookie ; then debug "Synced PulseAudio cookie from remote host $remote_ip." return 0 else @@ -446,10 +475,27 @@ do_stop() { ## # Arguments -operation= +operations=() +cookie= +no_more_options=false +# shellcheck disable=SC2034 + +while [[ $# -gt 0 ]] ; do + arg=$1 + shift -for arg in "$@" ; do case "$arg" in + --) + no_more_options=true + ;; + --*) + "$no_more_options" && { gui=false error "Option arguments may not preceed non-option arguments." ; exit 1 ; } + ;;& + --cookie) + [[ $# -eq 0 ]] && { gui=false error "Missing argument for option \"--cookie\"" ; exit 1 ; } + cookie=$1 + shift + ;; --debug) debug_cmdline=true ;; @@ -460,11 +506,10 @@ for arg in "$@" ; do help_cmdline=true ;; start|stop|restart|setup|status) - [[ -z $operation ]] || { error "Multiple operations are not supported." ; exit 1 ; } - operation=$arg + operations+=("$arg") ;; *) - error "Unsupported argument (try \"--help\")" + gui=false error "Unsupported argument (try \"--help\")" exit 1 ;; esac @@ -473,6 +518,16 @@ done ## # Configuration +_ssh_arguments=( + -o + PasswordAuthentication=no +) + +if [[ -n $PULSEAUDIO_TCP_SSH_ADDARGS ]] ; then + read -r -a _ssh_additional_arguments <<< "$PULSEAUDIO_TCP_SSH_ADDARGS" + _ssh_arguments+=("${_ssh_additional_arguments[@]}") +fi + config_dir="$HOME"/.config/pulseaudio-tcp config=$config_dir/config.inc.sh @@ -489,6 +544,15 @@ fi if [[ $gui_cmdline = false ]] ; then gui=false +elif [[ -z $(type -p zenity) ]] ; then + gui=false + warning "Disabling GUI support, because command \"zenity\" was not found." +elif ! [[ -v DISPLAY ]] && ! [[ -v XDG_SESSION_TYPE ]] ; then + gui=false + warning "Disabling GUI support, because neither \"DISPLAY\" not \"XDG_SESSION_TYPE\ is set." +elif [[ $XDG_SESSION_TYPE = tty ]] ; then + gui=false + warning "Disabling GUI support, because \"XDG_SESSION_TYPE\ is set to \"tty\"." else gui=true fi @@ -496,46 +560,46 @@ fi ## # Main Program -rv=0 +for operation in "${operations[@]}" ; do + rv=0 -if test "$operation" = setup ; then - info "Entering setup mode ..." -else - if ! test -e "$config" ; then - error "Configfile $config does not exist (use \"$0 setup\" first)." - rv=1 - elif ! test -r "$config" ; then - error "Configfile $config is not readable." - rv=1 - elif ! test -f "$config" ; then - error "Configfile $config is not a regular file." - rv=1 - else - . "$config" + if [[ "$operation" != setup ]] ; then + if ! test -e "$config" ; then + error "Configfile $config does not exist (use \"$0 setup\" first)." + rv=1 + elif ! test -r "$config" ; then + error "Configfile $config is not readable." + rv=1 + elif ! test -f "$config" ; then + error "Configfile $config is not a regular file." + rv=1 + else + . "$config" - if [[ -z $remote_ip ]] ; then - error "\"remote_ip=\" not set in configfile $config." - rv=1 - elif [[ -z $remote_user ]] ; then - error "\"remote_user=\" not set in configfile $config." - rv=1 + if [[ -z $remote_ip ]] ; then + error "\"remote_ip=\" not set in configfile $config." + rv=1 + elif [[ -z $remote_user ]] ; then + error "\"remote_user=\" not set in configfile $config." + rv=1 + fi fi + + required_cmds=( jq pactl ssh ) + + for exe in "${required_cmds[@]}" ; do + if [[ -z $(type -p "$exe") ]] ; then + error "Required executable \"$exe\" not found." + rv=1 + fi + done fi - required_cmds=( jq pactl ssh ) - "$gui" && required_cmds+=( zenity ) + if [[ $rv -ne 0 ]] ; then + error "Preliminary checks failed, skipping operation." + break + fi - for exe in "${required_cmds[@]}" ; do - if [[ -z $(type -p "$exe") ]] ; then - error "Required executable \"$exe\" not found." - rv=1 - fi - done -fi - -if [[ $rv -ne 0 ]] ; then - error "Preliminary checks failed, skipping operation." -else case "$operation" in setup) do_setup @@ -563,6 +627,8 @@ else rv=1 ;; esac -fi + + [[ $rv -ne 0 ]] && break +done exit "$rv" diff --git a/pulseaudio-tcp.bash_completion b/pulseaudio-tcp.bash_completion index 522b513..962aea1 100644 --- a/pulseaudio-tcp.bash_completion +++ b/pulseaudio-tcp.bash_completion @@ -1,34 +1,27 @@ _pulseaudio_tcp_completions() { local \ command_list \ - command_pattern \ commands \ cur \ option_list \ options \ word - options=( "--debug" "--help" "--nogui" ) + options=( "--debug" "--help" "--no-gui" "--" ) commands=( "start" "stop" "status" "setup" "restart" ) cur=${COMP_WORDS[COMP_CWORD]} + more_options=true for word in "${COMP_WORDS[@]}" ; do [[ $word = "$cur" ]] && continue + [[ $word = -- ]] && more_options=false options=("${options[@]/$word}") commands=("${commands[@]/$word}") done - option_list="${options[*]}" - - printf -v command_pattern "%s|" "${commands[@]}" - command_pattern="(${command_pattern%?})" - - if [[ ${COMP_WORDS[*]} =~ $command_pattern ]] ; then - command_list="" - else - command_list="${commands[*]}" - fi + "$more_options" && option_list="${options[*]}" + command_list="${commands[*]}" mapfile -t COMPREPLY < <( compgen -W "$option_list $command_list" -- "$cur")