From 8c2bd951ae5ab02c5bf9cad499e23bfc1b9bf7fe Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 4 May 2017 14:46:58 +0200 Subject: [PATCH] Allow printing of custom arguments in help. --- client/common/cmdline.c | 107 ++++++++++++++++--------------- include/freerdp/client/cmdline.h | 15 ++++- winpr/include/winpr/cmdline.h | 16 +++-- winpr/libwinpr/utils/cmdline.c | 52 +++++++-------- 4 files changed, 102 insertions(+), 88 deletions(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 950162840..63edc3ec4 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -199,36 +199,23 @@ static COMMAND_LINE_ARGUMENT_A args[] = { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } }; -BOOL freerdp_client_print_version() +BOOL freerdp_client_print_version(void) { printf("This is FreeRDP version %s (%s)\n", FREERDP_VERSION_FULL, GIT_REVISION); return TRUE; } -BOOL freerdp_client_print_buildconfig() +BOOL freerdp_client_print_buildconfig(void) { printf("%s", freerdp_get_build_config()); return TRUE; } -BOOL freerdp_client_print_command_line_help(int argc, char** argv) +static void freerdp_client_print_command_line_args(COMMAND_LINE_ARGUMENT_A* arg) { - char* str; - int length; - COMMAND_LINE_ARGUMENT_A* arg; - printf("\n"); - printf("FreeRDP - A Free Remote Desktop Protocol Implementation\n"); - printf("See www.freerdp.com for more information\n"); - printf("\n"); - printf("Usage: %s [file] [options] [/v:[:port]]\n", argv[0]); - printf("\n"); - printf("Syntax:\n"); - printf(" /flag (enables flag)\n"); - printf(" /option: (specifies option with value)\n"); - printf(" +toggle -toggle (enables or disables toggle, where '/' is a synonym of '+')\n"); - printf("\n"); - arg = args; + if (!arg) + return; do { @@ -242,12 +229,12 @@ BOOL freerdp_client_print_command_line_help(int argc, char** argv) || (arg->Flags & COMMAND_LINE_VALUE_OPTIONAL)) { BOOL overlong = FALSE; - printf(" %s", "/"); if (arg->Format) { - length = (int)(strlen(arg->Name) + strlen(arg->Format) + 2); + size_t length = (strlen(arg->Name) + strlen(arg->Format) + 2); + if (arg->Flags & COMMAND_LINE_VALUE_OPTIONAL) length += 2; @@ -257,18 +244,10 @@ BOOL freerdp_client_print_command_line_help(int argc, char** argv) overlong = TRUE; } - str = (char*) calloc(length + 1UL, sizeof(char)); - - if (!str) - return FALSE; - if (arg->Flags & COMMAND_LINE_VALUE_OPTIONAL) - sprintf_s(str, length + 1, "%s[:%s]", arg->Name, overlong ? "..." : arg->Format); + printf("%s[:%s]", arg->Name, overlong ? "..." : arg->Format); else - sprintf_s(str, length + 1, "%s:%s", arg->Name, overlong ? "..." : arg->Format); - printf("%-20s", str); - - free(str); + printf("%s:%s", arg->Name, overlong ? "..." : arg->Format); } else { @@ -285,7 +264,29 @@ BOOL freerdp_client_print_command_line_help(int argc, char** argv) } } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); +} +BOOL freerdp_client_print_command_line_help(int argc, char** argv) +{ + return freerdp_client_print_command_line_help_ex(argc, argv, NULL); +} + +BOOL freerdp_client_print_command_line_help_ex(int argc, char** argv, + COMMAND_LINE_ARGUMENT_A* custom) +{ + printf("\n"); + printf("FreeRDP - A Free Remote Desktop Protocol Implementation\n"); + printf("See www.freerdp.com for more information\n"); + printf("\n"); + printf("Usage: %s [file] [options] [/v:[:port]]\n", argv[0]); + printf("\n"); + printf("Syntax:\n"); + printf(" /flag (enables flag)\n"); + printf(" /option: (specifies option with value)\n"); + printf(" +toggle -toggle (enables or disables toggle, where '/' is a synonym of '+')\n"); + printf("\n"); + freerdp_client_print_command_line_args(custom); + freerdp_client_print_command_line_args(args); printf("\n"); printf("Examples:\n"); printf(" xfreerdp connection.rdp /p:Pwd123! /f\n"); @@ -311,7 +312,6 @@ BOOL freerdp_client_print_command_line_help(int argc, char** argv) printf("Multimedia Redirection: /multimedia:sys:alsa\n"); printf("USB Device Redirection: /usb:id,dev:054c:0268\n"); printf("\n"); - printf("For Gateways, the https_proxy environment variable is respected:\n"); #ifdef _WIN32 printf(" set HTTPS_PROXY=http://proxy.contoso.com:3128/\n"); @@ -320,7 +320,6 @@ BOOL freerdp_client_print_command_line_help(int argc, char** argv) #endif printf(" xfreerdp /g:rdp.contoso.com ...\n"); printf("\n"); - printf("More documentation is coming, in the meantime consult source files\n"); printf("\n"); return TRUE; @@ -867,24 +866,13 @@ static int freerdp_client_command_line_post_filter(void* context, } CommandLineSwitchCase(arg, "smartcard") { - if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) - { - char** p; - int count; - p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value, - &count); - p[0] = "smartcard"; - status = freerdp_client_add_device_channel(settings, count, p); - free(p); - } - else - { - char* p[1]; - int count; - count = 1; - p[0] = "smartcard"; - status = freerdp_client_add_device_channel(settings, count, p); - } + char** p; + int count; + p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value, + &count); + p[0] = "smartcard"; + status = freerdp_client_add_device_channel(settings, count, p); + free(p); } CommandLineSwitchCase(arg, "printer") { @@ -1395,6 +1383,13 @@ static BOOL freerdp_client_detect_command_line(int argc, char** argv, int freerdp_client_settings_command_line_status_print(rdpSettings* settings, int status, int argc, char** argv) +{ + return freerdp_client_settings_command_line_status_print_ex( + settings, status, argc, argv, NULL); +} + +int freerdp_client_settings_command_line_status_print_ex(rdpSettings* settings, + int status, int argc, char** argv, COMMAND_LINE_ARGUMENT_A* custom) { COMMAND_LINE_ARGUMENT_A* arg; @@ -1456,7 +1451,7 @@ int freerdp_client_settings_command_line_status_print(rdpSettings* settings, } else if (status < 0) { - freerdp_client_print_command_line_help(argc, argv); + freerdp_client_print_command_line_help_ex(argc, argv, custom); return COMMAND_LINE_STATUS_PRINT_HELP; } @@ -1621,6 +1616,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, settings->PercentScreenUseWidth = 1; partial = TRUE; } + if (strchr(p, 'h')) { settings->PercentScreenUseHeight = 1; @@ -2148,6 +2144,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if (arg->Value) { #ifdef WITH_GFX_H264 + if (_strnicmp("AVC444", arg->Value, 6) == 0) { settings->GfxH264 = TRUE; @@ -2159,15 +2156,17 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } else #endif - if (_strnicmp("RFX", arg->Value, 3) != 0) - return COMMAND_LINE_ERROR; + if (_strnicmp("RFX", arg->Value, 3) != 0) + return COMMAND_LINE_ERROR; } } CommandLineSwitchCase(arg, "gfx-thin-client") { settings->GfxThinClient = arg->Value ? TRUE : FALSE; + if (settings->GfxThinClient) settings->GfxSmallCache = TRUE; + settings->SupportGraphicsPipeline = TRUE; } CommandLineSwitchCase(arg, "gfx-small-cache") @@ -2427,6 +2426,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, { settings->NSCodec = TRUE; } + #if defined(WITH_JPEG) else if (strcmp(arg->Value, "jpeg") == 0) { @@ -2435,6 +2435,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if (settings->JpegQuality == 0) settings->JpegQuality = 75; } + #endif } CommandLineSwitchCase(arg, "fast-path") diff --git a/include/freerdp/client/cmdline.h b/include/freerdp/client/cmdline.h index 621a9976e..4c4337ea0 100644 --- a/include/freerdp/client/cmdline.h +++ b/include/freerdp/client/cmdline.h @@ -20,6 +20,8 @@ #ifndef FREERDP_CLIENT_CMDLINE_H #define FREERDP_CLIENT_CMDLINE_H +#include + #include #include @@ -28,13 +30,19 @@ extern "C" { #endif FREERDP_API int freerdp_client_settings_parse_command_line_arguments( - rdpSettings* settings, int argc, char** argv, BOOL allowUnknown); -FREERDP_API int freerdp_client_settings_command_line_status_print(rdpSettings* settings, int status, int argc, char** argv); + rdpSettings* settings, int argc, char** argv, BOOL allowUnknown); +FREERDP_API int freerdp_client_settings_command_line_status_print( + rdpSettings* settings, int status, int argc, char** argv); +FREERDP_API int freerdp_client_settings_command_line_status_print_ex( + rdpSettings* settings, int status, int argc, char** argv, + COMMAND_LINE_ARGUMENT_A* custom); FREERDP_API BOOL freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings); FREERDP_API BOOL freerdp_client_print_version(void); FREERDP_API BOOL freerdp_client_print_buildconfig(void); FREERDP_API BOOL freerdp_client_print_command_line_help(int argc, char** argv); +FREERDP_API BOOL freerdp_client_print_command_line_help_ex( + int argc, char** argv, COMMAND_LINE_ARGUMENT_A* custom); FREERDP_API BOOL freerdp_parse_username(char* username, char** user, char** domain); FREERDP_API BOOL freerdp_parse_hostname(char* hostname, char** host, int* port); @@ -42,7 +50,8 @@ FREERDP_API BOOL freerdp_set_connection_type(rdpSettings* settings, int type); FREERDP_API BOOL freerdp_client_add_device_channel(rdpSettings* settings, int count, char** params); FREERDP_API BOOL freerdp_client_add_static_channel(rdpSettings* settings, int count, char** params); -FREERDP_API BOOL freerdp_client_add_dynamic_channel(rdpSettings* settings, int count, char** params); +FREERDP_API BOOL freerdp_client_add_dynamic_channel(rdpSettings* settings, int count, + char** params); #ifdef __cplusplus } diff --git a/winpr/include/winpr/cmdline.h b/winpr/include/winpr/cmdline.h index b843ee7eb..2452ad4a9 100644 --- a/winpr/include/winpr/cmdline.h +++ b/winpr/include/winpr/cmdline.h @@ -137,13 +137,17 @@ extern "C" { WINPR_API int CommandLineClearArgumentsA(COMMAND_LINE_ARGUMENT_A* options); WINPR_API int CommandLineClearArgumentsW(COMMAND_LINE_ARGUMENT_W* options); -WINPR_API int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* options, DWORD flags, - void* context, COMMAND_LINE_PRE_FILTER_FN_A preFilter, COMMAND_LINE_POST_FILTER_FN_A postFilter); -WINPR_API int CommandLineParseArgumentsW(int argc, LPCWSTR* argv, COMMAND_LINE_ARGUMENT_W* options, DWORD flags, - void* context, COMMAND_LINE_PRE_FILTER_FN_W preFilter, COMMAND_LINE_POST_FILTER_FN_W postFilter); +WINPR_API int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* options, + DWORD flags, + void* context, COMMAND_LINE_PRE_FILTER_FN_A preFilter, COMMAND_LINE_POST_FILTER_FN_A postFilter); +WINPR_API int CommandLineParseArgumentsW(int argc, LPCWSTR* argv, COMMAND_LINE_ARGUMENT_W* options, + DWORD flags, + void* context, COMMAND_LINE_PRE_FILTER_FN_W preFilter, COMMAND_LINE_POST_FILTER_FN_W postFilter); -WINPR_API COMMAND_LINE_ARGUMENT_A* CommandLineFindArgumentA(COMMAND_LINE_ARGUMENT_A* options, LPCSTR Name); -WINPR_API COMMAND_LINE_ARGUMENT_W* CommandLineFindArgumentW(COMMAND_LINE_ARGUMENT_W* options, LPCWSTR Name); +WINPR_API COMMAND_LINE_ARGUMENT_A* CommandLineFindArgumentA(COMMAND_LINE_ARGUMENT_A* options, + LPCSTR Name); +WINPR_API COMMAND_LINE_ARGUMENT_W* CommandLineFindArgumentW(COMMAND_LINE_ARGUMENT_W* options, + LPCWSTR Name); WINPR_API COMMAND_LINE_ARGUMENT_A* CommandLineFindNextArgumentA(COMMAND_LINE_ARGUMENT_A* argument); diff --git a/winpr/libwinpr/utils/cmdline.c b/winpr/libwinpr/utils/cmdline.c index 19e4eabc6..fef6639c1 100644 --- a/winpr/libwinpr/utils/cmdline.c +++ b/winpr/libwinpr/utils/cmdline.c @@ -45,8 +45,9 @@ * */ -int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* options, DWORD flags, - void* context, COMMAND_LINE_PRE_FILTER_FN_A preFilter, COMMAND_LINE_POST_FILTER_FN_A postFilter) +int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* options, + DWORD flags, + void* context, COMMAND_LINE_PRE_FILTER_FN_A preFilter, COMMAND_LINE_POST_FILTER_FN_A postFilter) { int i, j; int status; @@ -71,9 +72,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* int value_length; int value_index; int toggle; - status = 0; - match = FALSE; found = FALSE; argument = FALSE; @@ -92,7 +91,6 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* for (i = 1; i < argc; i++) { index = i; - escaped = TRUE; if (preFilter) @@ -146,7 +144,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* else if (flags & COMMAND_LINE_SIGIL_NOT_ESCAPED) { if (notescaped) - return COMMAND_LINE_ERROR; + return COMMAND_LINE_ERROR; sigil_length = 0; escaped = FALSE; @@ -158,17 +156,18 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* } if ((sigil_length > 0) || (flags & COMMAND_LINE_SIGIL_NONE) || - (flags & COMMAND_LINE_SIGIL_NOT_ESCAPED)) + (flags & COMMAND_LINE_SIGIL_NOT_ESCAPED)) { - if (length < (sigil_length + 1)) { + if (length < (sigil_length + 1)) + { if ((flags & COMMAND_LINE_IGN_UNKNOWN_KEYWORD)) continue; + return COMMAND_LINE_ERROR_NO_KEYWORD; } keyword_index = sigil_index + sigil_length; keyword = (char*) &argv[i][keyword_index]; - toggle = -1; if (flags & COMMAND_LINE_SIGIL_ENABLE_DISABLE) @@ -198,10 +197,8 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* if (separator) { separator_length = 1; - separator_index = (int) (separator - argv[i]); - - keyword_length = (int) (separator - keyword); - + separator_index = (int)(separator - argv[i]); + keyword_length = (int)(separator - keyword); value_index = separator_index + separator_length; value = (char*) &argv[i][value_index]; value_length = (length - value_index); @@ -211,7 +208,6 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* separator_length = 0; separator_index = -1; keyword_length = (length - keyword_index); - value_index = -1; value = NULL; value_length = 0; @@ -221,6 +217,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* continue; found = FALSE; + for (j = 0; options[j].Name != NULL; j++) { match = FALSE; @@ -269,17 +266,16 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* } if ((options[j].Flags & COMMAND_LINE_VALUE_REQUIRED) || - (options[j].Flags & COMMAND_LINE_VALUE_OPTIONAL)) + (options[j].Flags & COMMAND_LINE_VALUE_OPTIONAL)) argument = TRUE; else argument = FALSE; - + if (value_present && argument) { i++; value_index = 0; length = (int) strlen(argv[i]); - value = (char*) &argv[i][value_index]; value_length = (length - value_index); } @@ -358,15 +354,15 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* postFilter(context, &options[j]); if (options[j].Flags & COMMAND_LINE_PRINT) - return COMMAND_LINE_STATUS_PRINT; + return COMMAND_LINE_STATUS_PRINT; else if (options[j].Flags & COMMAND_LINE_PRINT_HELP) - return COMMAND_LINE_STATUS_PRINT_HELP; + return COMMAND_LINE_STATUS_PRINT_HELP; else if (options[j].Flags & COMMAND_LINE_PRINT_VERSION) - return COMMAND_LINE_STATUS_PRINT_VERSION; + return COMMAND_LINE_STATUS_PRINT_VERSION; else if (options[j].Flags & COMMAND_LINE_PRINT_BUILDCONFIG) - return COMMAND_LINE_STATUS_PRINT_BUILDCONFIG; + return COMMAND_LINE_STATUS_PRINT_BUILDCONFIG; } - + if (!found && (flags & COMMAND_LINE_IGN_UNKNOWN_KEYWORD) == 0) return COMMAND_LINE_ERROR_NO_KEYWORD; } @@ -375,8 +371,9 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* return status; } -int CommandLineParseArgumentsW(int argc, LPCWSTR* argv, COMMAND_LINE_ARGUMENT_W* options, DWORD flags, - void* context, COMMAND_LINE_PRE_FILTER_FN_W preFilter, COMMAND_LINE_POST_FILTER_FN_W postFilter) +int CommandLineParseArgumentsW(int argc, LPCWSTR* argv, COMMAND_LINE_ARGUMENT_W* options, + DWORD flags, + void* context, COMMAND_LINE_PRE_FILTER_FN_W preFilter, COMMAND_LINE_POST_FILTER_FN_W postFilter) { return 0; } @@ -409,7 +406,7 @@ int CommandLineClearArgumentsW(COMMAND_LINE_ARGUMENT_W* options) COMMAND_LINE_ARGUMENT_A* CommandLineFindArgumentA(COMMAND_LINE_ARGUMENT_A* options, LPCSTR Name) { - int i; + size_t i; for (i = 0; options[i].Name != NULL; i++) { @@ -428,7 +425,7 @@ COMMAND_LINE_ARGUMENT_A* CommandLineFindArgumentA(COMMAND_LINE_ARGUMENT_A* optio COMMAND_LINE_ARGUMENT_W* CommandLineFindArgumentW(COMMAND_LINE_ARGUMENT_W* options, LPCWSTR Name) { - int i; + size_t i; for (i = 0; options[i].Name != NULL; i++) { @@ -449,6 +446,9 @@ COMMAND_LINE_ARGUMENT_A* CommandLineFindNextArgumentA(COMMAND_LINE_ARGUMENT_A* a { COMMAND_LINE_ARGUMENT_A* nextArgument; + if (!argument) + return NULL; + nextArgument = &argument[1]; if (nextArgument->Name == NULL)