diff --git a/res/Makefile.am b/res/Makefile.am index e4d879e..9e73673 100644 --- a/res/Makefile.am +++ b/res/Makefile.am @@ -3,3 +3,7 @@ EXTRA_DIST = wpa.conf dbuspolicydir=$(sysconfdir)/dbus-1/system.d dbuspolicy_DATA = org.freedesktop.miracle.conf + +bashcompletiondir=${datadir}/bash-completion/completions +bashcompletion_DATA=miraclecast-completion + diff --git a/res/miraclecast-completion b/res/miraclecast-completion index 707ccad..1d82b32 100755 --- a/res/miraclecast-completion +++ b/res/miraclecast-completion @@ -1,3 +1,11 @@ +#!/bin/bash + +# +# Autocompletion for miraclecast commands +# +# Maintainer: Alberto Fanjul +# + function _miracle-wifid() { local cur prev @@ -15,7 +23,7 @@ function _miracle-wifid() { ;; esac - COMPREPLY=($(compgen -W "$(_parse_help miracle-wifid)" -- "$cur")) + COMPREPLY=($(compgen -W "$(_parse_help miracle-wifid) $(_parse_short_help miracle-wifid)" -- "$cur")) } complete -F _miracle-wifid miracle-wifid @@ -33,7 +41,7 @@ function _miracle-sinkctl() { ;; esac - COMPREPLY=($(compgen -W "$(_parse_help miracle-sinkctl)" -- "$cur")) + COMPREPLY=($(compgen -W "$(_parse_help miracle-sinkctl) $(_parse_short_help miracle-sinkctl)" -- "$cur")) } complete -F _miracle-sinkctl miracle-sinkctl @@ -51,7 +59,68 @@ function _miracle-wifictl() { ;; esac - COMPREPLY=($(compgen -W "$(_parse_help miracle-wifictl)" -- "$cur")) + COMPREPLY=($(compgen -W "$(_parse_help miracle-wifictl) $(_parse_short_help miracle-wifictl)" -- "$cur")) } complete -F _miracle-wifictl miracle-wifictl + +_parse_short_help () +{ + eval local cmd=$( quote "$1" ); + local line; + { + case $cmd in + -) + cat + ;; + *) + LC_ALL=C "$( dequote "$cmd" )" ${2:---help} 2>&1 + ;; + esac + } | while read -r line; do + [[ $line == *([[:blank:]])-* ]] || continue; + while [[ $line =~ ((^|[^-])-[A-Za-z0-9?][[:space:]]+)\[?[A-Z0-9]+\]? ]]; do + line=${line/"${BASH_REMATCH[0]}"/"${BASH_REMATCH[1]}"}; + done; + __parse_short_options "${line// or /, }"; + done +} + +__parse_short_options () +{ + local option option2 i IFS=' +,/|'; + option=; + local -a array; + read -a array <<< "$1"; + for i in "${array[@]}"; + do + case "$i" in + ---*) + break + ;; + --?*) + break + ;; + -?*) + option=$i; + break + ;; + *) + break + ;; + esac; + done; + [[ -n $option ]] || return; + IFS=' +'; + if [[ $option =~ (\[((no|dont)-?)\]). ]]; then + option2=${option/"${BASH_REMATCH[1]}"/}; + option2=${option2%%[<{().[]*}; + printf '%s\n' "${option2/=*/=}"; + option=${option/"${BASH_REMATCH[1]}"/"${BASH_REMATCH[2]}"}; + fi; + option=${option%%[<{().[]*}; + printf '%s\n' "${option/=*/=}" +} + diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index dd61ff0..c1e5855 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -93,13 +93,10 @@ void cli_printf(const char *fmt, ...) va_end(args); } -int cli_help(const struct cli_cmd *cmds) +int cli_help(const struct cli_cmd *cmds, int whitespace) { unsigned int i; - if (!is_cli()) { - cli_fn_help(); - } cli_printf("Available commands:\n"); for (i = 0; cmds[i].cmd; ++i) { @@ -112,7 +109,7 @@ int cli_help(const struct cli_cmd *cmds) cli_printf(" %s %-*s %s\n", cmds[i].cmd, - (int)(40 - strlen(cmds[i].cmd)), + (int)(whitespace - strlen(cmds[i].cmd)), cmds[i].args ? : "", cmds[i].desc ? : ""); } @@ -173,7 +170,7 @@ int cli_do(const struct cli_cmd *cmds, char **args, unsigned int n) } if (!strcmp(cmd, "help")) - return cli_help(cmds); + return cli_help(cmds, 40); return -EAGAIN; } diff --git a/src/ctl/ctl.h b/src/ctl/ctl.h index 75cc0a3..1d0bd9a 100644 --- a/src/ctl/ctl.h +++ b/src/ctl/ctl.h @@ -220,7 +220,7 @@ int cli_run(void); void cli_exit(void); bool cli_running(void); -int cli_help(const struct cli_cmd *cmds); +int cli_help(const struct cli_cmd *cmds, int whitespace); int cli_do(const struct cli_cmd *cmds, char **args, unsigned int n); /* callback functions */ diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index c1b8b68..5514a86 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -677,6 +677,7 @@ void cli_fn_help() printf("%s [OPTIONS...] ...\n\n" "Control a dedicated local sink via MiracleCast.\n" " -h --help Show this help\n" + " --help-commands Show avaliable commands\n" " --version Show package version\n" " --log-level Maximum level for log messages\n" " --log-journal-level Maximum level for journal log messages\n" @@ -690,11 +691,11 @@ void cli_fn_help() " default CEA %08X\n" " default VESA %08X\n" " default HH %08X\n" + " --help-res Shows avaliable values for res\n" "\n" , program_invocation_short_name, gst_audio_en, DEFAULT_RSTP_PORT, wfd_supported_res_cea, wfd_supported_res_vesa, wfd_supported_res_hh ); - wfd_print_resolutions(); /* * 80-char barrier: * 01234567890123456789012345678901234567890123456789012345678901234567890123456789 @@ -771,10 +772,13 @@ static int parse_argv(int argc, char *argv[]) ARG_AUDIO, ARG_SCALE, ARG_RES, + ARG_HELP_RES, ARG_UIBC, + ARG_HELP_COMMANDS, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, + { "help-commands", no_argument, NULL, ARG_HELP_COMMANDS }, { "version", no_argument, NULL, ARG_VERSION }, { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, { "log-journal-level", required_argument, NULL, ARG_JOURNAL_LEVEL }, @@ -782,6 +786,7 @@ static int parse_argv(int argc, char *argv[]) { "audio", required_argument, NULL, ARG_AUDIO }, { "scale", required_argument, NULL, ARG_SCALE }, { "res", required_argument, NULL, ARG_RES }, + { "help-res", no_argument, NULL, ARG_HELP_RES }, { "port", required_argument, NULL, 'p' }, { "uibc", no_argument, NULL, ARG_UIBC }, { "external-player", required_argument, NULL, 'e' }, @@ -794,10 +799,16 @@ static int parse_argv(int argc, char *argv[]) external_player = false; rstp_port = DEFAULT_RSTP_PORT; - while ((c = getopt_long(argc, argv, "he:p", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "he:p:", options, NULL)) >= 0) { switch (c) { case 'h': - return cli_help(cli_cmds); + cli_fn_help(); + return 0; + case ARG_HELP_COMMANDS: + return cli_help(cli_cmds, 20); + case ARG_HELP_RES: + wfd_print_resolutions(""); + return 0; case ARG_VERSION: puts(PACKAGE_STRING); return 0; diff --git a/src/ctl/wfd.c b/src/ctl/wfd.c index 87c3922..49ee5d3 100644 --- a/src/ctl/wfd.c +++ b/src/ctl/wfd.c @@ -103,27 +103,27 @@ struct resolution_bitmap resolutions_hh[] = { {0, 0, 0, 0}, }; -void wfd_print_resolutions(void) +void wfd_print_resolutions(char * prefix) { int i; - printf("CEA resolutions:\n"); + printf("%sCEA resolutions:\n", prefix); for (i = 0; resolutions_cea[i].hres != 0; i++) { - printf("\t%2d %08x %4dx%4d@%d\n", + printf("%s\t%2d %08x %4dx%4d@%d\n", prefix, resolutions_cea[i].index, 1 << resolutions_cea[i].index, resolutions_cea[i].hres, resolutions_cea[i].vres, resolutions_cea[i].fps); } - printf("VESA resolutions:\n"); + printf("%sVESA resolutions:\n", prefix); for (i = 0; resolutions_vesa[i].hres != 0; i++) { - printf("\t%2d %08x %4dx%4d@%d\n", + printf("%s\t%2d %08x %4dx%4d@%d\n", prefix, resolutions_vesa[i].index, 1 << resolutions_vesa[i].index, resolutions_vesa[i].hres, resolutions_vesa[i].vres, resolutions_vesa[i].fps); } - printf("HH resolutions:\n"); + printf("%sHH resolutions:\n", prefix); for (i = 0; resolutions_hh[i].hres != 0; i++) { - printf("\t%2d %08x %4dx%4d@%d\n", + printf("%s\t%2d %08x %4dx%4d@%d\n", prefix, resolutions_hh[i].index, 1 << resolutions_hh[i].index, resolutions_hh[i].hres, resolutions_hh[i].vres, resolutions_hh[i].fps); diff --git a/src/ctl/wfd.h b/src/ctl/wfd.h index 2d85111..d9a5831 100644 --- a/src/ctl/wfd.h +++ b/src/ctl/wfd.h @@ -21,7 +21,7 @@ #ifndef WFD_H #define WFD_H -void wfd_print_resolutions(void); +void wfd_print_resolutions(char * prefix); int vfd_get_cea_resolution(uint32_t mask, int *hres, int *vres); int vfd_get_vesa_resolution(uint32_t mask, int *hres, int *vres); int vfd_get_hh_resolution(uint32_t mask, int *hres, int *vres); diff --git a/src/ctl/wifictl.c b/src/ctl/wifictl.c index f8bf7e5..7058d2c 100644 --- a/src/ctl/wifictl.c +++ b/src/ctl/wifictl.c @@ -420,6 +420,7 @@ void cli_fn_help() "Send control command to or query the MiracleCast Wifi-Manager. If no arguments\n" "are given, an interactive command-line tool is provided.\n\n" " -h --help Show this help\n" + " --help-commands Show avaliable commands\n" " --version Show package version\n" " --log-level Maximum level for log messages\n" "\n" @@ -497,9 +498,11 @@ static int parse_argv(int argc, char *argv[]) enum { ARG_VERSION = 0x100, ARG_LOG_LEVEL, + ARG_HELP_COMMANDS, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, + { "help-commands", no_argument, NULL, ARG_HELP_COMMANDS }, { "version", no_argument, NULL, ARG_VERSION }, { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, {} @@ -509,7 +512,10 @@ static int parse_argv(int argc, char *argv[]) while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { switch (c) { case 'h': - return cli_help(cli_cmds); + cli_fn_help(); + return 0; + case ARG_HELP_COMMANDS: + return cli_help(cli_cmds, 20); case ARG_VERSION: puts(PACKAGE_STRING); return 0; diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index 026a0ae..ca7e461 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -541,12 +541,6 @@ int main(int argc, char **argv) struct manager *m = NULL; int r; - if (getuid() != 0) { - r = EACCES; - log_notice("Must run as root"); - goto finish; - } - srand(time(NULL)); r = parse_argv(argc, argv); @@ -555,6 +549,12 @@ int main(int argc, char **argv) if (!r) return EXIT_SUCCESS; + if (getuid() != 0) { + r = EACCES; + log_notice("Must run as root"); + goto finish; + } + r = manager_new(&m); if (r < 0) goto finish;