libfreerdp-client: introduce CLI compatibility layer and migration assistant
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Wed, 5 Dec 2012 17:12:18 +0000 (12:12 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Wed, 5 Dec 2012 17:12:18 +0000 (12:12 -0500)
client/common/CMakeLists.txt
client/common/cmdline.c
client/common/compatibility.c [new file with mode: 0644]
client/common/compatibility.h [new file with mode: 0644]
include/freerdp/client/cmdline.h
winpr/include/winpr/cmdline.h
winpr/libwinpr/utils/cmdline.c

index 876560d..e249cd0 100644 (file)
@@ -21,6 +21,8 @@ set(MODULE_PREFIX "FREERDP_CLIENT")
 set(${MODULE_PREFIX}_SRCS
        client.c
        cmdline.c
+       compatibility.c
+       compatibility.h
        file.c)
 
 set(FREERDP_CHANNELS_CLIENT_PATH "../../channels/client")
index c6d8b33..6f98118 100644 (file)
@@ -31,6 +31,8 @@
 
 #include <freerdp/client/cmdline.h>
 
+#include "compatibility.h"
+
 COMMAND_LINE_ARGUMENT_A args[] =
 {
        { "v", COMMAND_LINE_VALUE_REQUIRED, "<server>[:port]", NULL, NULL, -1, NULL, "Server hostname" },
@@ -109,24 +111,6 @@ COMMAND_LINE_ARGUMENT_A args[] =
        { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
 };
 
-BOOL freerdp_detect_windows_style_command_line_syntax(int argc, char** argv)
-{
-       int index;
-
-       for (index = 1; index < argc; index++)
-       {
-               if (argv[index][0] == '/')
-                       return TRUE;
-       }
-
-       return FALSE;
-}
-
-BOOL freerdp_detect_posix_style_command_line_syntax(int argc, char** argv)
-{
-       return (!freerdp_detect_windows_style_command_line_syntax(argc, argv));
-}
-
 int freerdp_client_print_version()
 {
        printf("This is FreeRDP version %s (git %s)\n", FREERDP_VERSION_FULL, GIT_REVISION);
@@ -232,21 +216,21 @@ int freerdp_client_print_command_line_help(int argc, char** argv)
        return 1;
 }
 
-int freerdp_client_command_line_pre_filter(void* context, int index, LPCSTR arg)
+int freerdp_client_command_line_pre_filter(void* context, int index, int argc, LPCSTR* argv)
 {
        if (index == 1)
        {
                int length;
                rdpSettings* settings;
 
-               length = strlen(arg);
+               length = strlen(argv[index]);
 
                if (length > 4)
                {
-                       if (_stricmp(&arg[length - 4], ".rdp") == 0)
+                       if (_stricmp(&(argv[index])[length - 4], ".rdp") == 0)
                        {
                                settings = (rdpSettings*) context;
-                               settings->ConnectionFile = _strdup(arg);
+                               settings->ConnectionFile = _strdup(argv[index]);
                        }
                }
        }
@@ -626,6 +610,118 @@ int freerdp_map_keyboard_layout_name_to_id(char* name)
        return 0;
 }
 
+int freerdp_detect_windows_style_command_line_syntax(int argc, char** argv, int* count)
+{
+       int status;
+       DWORD flags;
+       int detect_status;
+       COMMAND_LINE_ARGUMENT_A* arg;
+
+       flags = COMMAND_LINE_SEPARATOR_COLON;
+       flags |= COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SIGIL_PLUS_MINUS;
+
+       *count = 0;
+       detect_status = 0;
+       CommandLineClearArgumentsA(args);
+       status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, NULL, NULL, NULL);
+
+       arg = args;
+
+       do
+       {
+               if (!(arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT))
+                       continue;
+
+               (*count)++;
+       }
+       while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
+
+       if (detect_status == 0)
+       {
+               if ((status <= COMMAND_LINE_ERROR) && (status >= COMMAND_LINE_ERROR_LAST))
+                       detect_status = -1;
+       }
+
+       return 0;
+}
+
+int freerdp_detect_posix_style_command_line_syntax(int argc, char** argv, int* count)
+{
+       int status;
+       DWORD flags;
+       int detect_status;
+       COMMAND_LINE_ARGUMENT_A* arg;
+
+       flags = COMMAND_LINE_SEPARATOR_SPACE;
+       flags |= COMMAND_LINE_SIGIL_DASH | COMMAND_LINE_SIGIL_DOUBLE_DASH;
+       flags |= COMMAND_LINE_SIGIL_ENABLE_DISABLE;
+
+       *count = 0;
+       detect_status = 0;
+       CommandLineClearArgumentsA(args);
+       status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, NULL, NULL, NULL);
+
+       arg = args;
+
+       do
+       {
+               if (!(arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT))
+                       continue;
+
+               (*count)++;
+       }
+       while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
+
+       if (detect_status == 0)
+       {
+               if ((status <= COMMAND_LINE_ERROR) && (status >= COMMAND_LINE_ERROR_LAST))
+                       detect_status = -1;
+       }
+
+       return 0;
+}
+
+BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* flags)
+{
+       int old_cli_status;
+       int old_cli_count;
+       int posix_cli_status;
+       int posix_cli_count;
+       int windows_cli_status;
+       int windows_cli_count;
+       BOOL compatibility = FALSE;
+
+       windows_cli_status = freerdp_detect_windows_style_command_line_syntax(argc, argv, &windows_cli_count);
+       posix_cli_status = freerdp_detect_posix_style_command_line_syntax(argc, argv, &posix_cli_count);
+       old_cli_status = freerdp_detect_old_command_line_syntax(argc, argv, &old_cli_count);
+
+       /* Default is POSIX syntax */
+       *flags = COMMAND_LINE_SEPARATOR_SPACE;
+       *flags |= COMMAND_LINE_SIGIL_DASH | COMMAND_LINE_SIGIL_DOUBLE_DASH;
+       *flags |= COMMAND_LINE_SIGIL_ENABLE_DISABLE;
+
+       if (windows_cli_count > posix_cli_count)
+       {
+               *flags = COMMAND_LINE_SEPARATOR_COLON;
+               *flags |= COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SIGIL_PLUS_MINUS;
+       }
+       else
+       {
+               if ((old_cli_status == 1) || ((old_cli_count > posix_cli_count) && (old_cli_status != -1)))
+               {
+                       *flags = COMMAND_LINE_SEPARATOR_SPACE;
+                       *flags |= COMMAND_LINE_SIGIL_DASH | COMMAND_LINE_SIGIL_DOUBLE_DASH;
+
+                       compatibility = TRUE;
+               }
+       }
+
+       //printf("windows: %d/%d posix: %d/%d compat: %d/%d\n", windows_cli_status, windows_cli_count,
+       //              posix_cli_status, posix_cli_count, old_cli_status, old_cli_count);
+
+       return compatibility;
+}
+
 int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettings* settings)
 {
        char* p;
@@ -633,25 +729,25 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
        int length;
        int status;
        DWORD flags;
+       BOOL compatibility;
        COMMAND_LINE_ARGUMENT_A* arg;
 
        freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0);
 
-       if (freerdp_detect_windows_style_command_line_syntax(argc, argv))
+       compatibility = freerdp_client_detect_command_line(argc, argv, &flags);
+
+       if (compatibility)
        {
-               flags = COMMAND_LINE_SEPARATOR_COLON;
-               flags |= COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SIGIL_PLUS_MINUS;
+               printf("WARNING: Using deprecated command-line interface!\n");
+               return freerdp_client_parse_old_command_line_arguments(argc, argv, settings);
        }
        else
        {
-               flags = COMMAND_LINE_SEPARATOR_SPACE;
-               flags |= COMMAND_LINE_SIGIL_DASH | COMMAND_LINE_SIGIL_DOUBLE_DASH;
-               flags |= COMMAND_LINE_SIGIL_ENABLE_DISABLE;
+               CommandLineClearArgumentsA(args);
+               status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, settings,
+                               freerdp_client_command_line_pre_filter, freerdp_client_command_line_post_filter);
        }
 
-       status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, settings,
-                       freerdp_client_command_line_pre_filter, freerdp_client_command_line_post_filter);
-
        if (status == COMMAND_LINE_STATUS_PRINT_HELP)
        {
                freerdp_client_print_command_line_help(argc, argv);
diff --git a/client/common/compatibility.c b/client/common/compatibility.c
new file mode 100644 (file)
index 0000000..a580c90
--- /dev/null
@@ -0,0 +1,566 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Client Compatibility
+ *
+ * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <winpr/crt.h>
+#include <winpr/cmdline.h>
+
+#include <freerdp/addin.h>
+#include <freerdp/settings.h>
+#include <freerdp/client/channels.h>
+#include <freerdp/locale/keyboard.h>
+
+#include <freerdp/client/cmdline.h>
+
+#include "compatibility.h"
+
+COMMAND_LINE_ARGUMENT_A old_args[] =
+{
+       { "0", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "connect to console session" },
+       { "a", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "set color depth in bits, default is 16" },
+       { "c", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "shell working directory" },
+       { "D", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "hide window decorations" },
+       { "T", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Window title" },
+       { "d", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "domain" },
+       { "f", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "fullscreen mode" },
+       { "g", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "set geometry, using format WxH or X%% or 'workarea', default is 1024x768" },
+       { "h", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "help", "print this help" },
+       { "k", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "set keyboard layout ID" },
+       { "K", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "do not interfere with window manager bindings" },
+       { "n", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "hostname" },
+       { "o", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "console audio" },
+       { "p", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "password" },
+       { "s", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "set startup-shell" },
+       { "t", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "alternative port number, default is 3389" },
+       { "u", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "username" },
+       { "x", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "performance flags (m[odem], b[roadband] or l[an])" },
+       { "X", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "embed into another window with a given XID." },
+       { "z", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "enable compression" },
+       { "app", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "RemoteApp connection. This implies -g workarea" },
+       { "ext", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "load an extension" },
+       { "no-auth", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "disable authentication" },
+       { "authonly", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "authentication only, no UI" },
+       { "from-stdin", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "unspecified username, password, domain and hostname params are prompted" },
+       { "no-fastpath", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "disable fast-path" },
+       { "no-motion", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "don't send mouse motion events" },
+       { "gdi", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "graphics rendering (hw, sw)" },
+       { "no-osb", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "disable offscreen bitmaps" },
+       { "no-bmp-cache", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "disable bitmap cache" },
+       { "plugin", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "load a virtual channel plugin" },
+       { "rfx", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "enable RemoteFX" },
+       { "rfx-mode", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "RemoteFX operational flags (v[ideo], i[mage]), default is video" },
+       { "nsc", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "enable NSCodec (experimental)" },
+       { "disable-wallpaper", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "disables wallpaper" },
+       { "composition", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "enable desktop composition" },
+       { "disable-full-window-drag", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "disables full window drag" },
+       { "disable-menu-animations", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "disables menu animations" },
+       { "disable-theming", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "disables theming" },
+       { "no-rdp", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "disable Standard RDP encryption" },
+       { "no-tls", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "disable TLS encryption" },
+       { "no-nla", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "disable network level authentication" },
+       { "ntlm", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "force NTLM authentication protocol version (1 or 2)" },
+       { "ignore-certificate", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "ignore verification of logon certificate" },
+       { "sec", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "force protocol security (rdp, tls or nla)" },
+       { "secure-checksum", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "use salted checksums with Standard RDP encryption" },
+       { "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, NULL, "print version information" },
+       { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
+};
+
+void freerdp_client_old_parse_hostname(char* str, char** ServerHostname, UINT32* ServerPort)
+{
+       char* p;
+
+       if (str[0] == '[' && (p = strchr(str, ']'))
+                       && (p[1] == 0 || (p[1] == ':' && !strchr(p + 2, ':'))))
+       {
+               /* Either "[...]" or "[...]:..." with at most one : after the brackets */
+               *ServerHostname = _strdup(str + 1);
+
+               if ((p = strchr((char*) *ServerHostname, ']')))
+               {
+                       *p = 0;
+
+                       if (p[1] == ':')
+                               *ServerPort = atoi(p + 2);
+               }
+       }
+       else
+       {
+               /* Port number is cut off and used if exactly one : in the string */
+               *ServerHostname = _strdup(str);
+
+               if ((p = strchr((char*) *ServerHostname, ':')) && !strchr(p + 1, ':'))
+               {
+                       *p = 0;
+                       *ServerPort = atoi(p + 1);
+               }
+       }
+}
+
+int freerdp_client_old_command_line_pre_filter(void* context, int index, int argc, LPCSTR* argv)
+{
+       rdpSettings* settings;
+
+       if (index == (argc - 1))
+       {
+               if (argv[index][0] != '-')
+               {
+                       if ((strcmp(argv[index - 1], "-v") == 0) ||
+                                       (strcmp(argv[index - 1], "/v") == 0))
+                       {
+                               return -1;
+                       }
+
+                       if (context)
+                       {
+                               settings = (rdpSettings*) context;
+                               freerdp_client_old_parse_hostname((char*) argv[index], &settings->ServerHostname, &settings->ServerPort);
+                       }
+               }
+               else
+               {
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+int freerdp_client_old_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT_A* arg)
+{
+       return 0;
+}
+
+int freerdp_detect_old_command_line_syntax(int argc, char** argv, int* count)
+{
+       int status;
+       DWORD flags;
+       int detect_status;
+       rdpSettings* settings;
+       COMMAND_LINE_ARGUMENT_A* arg;
+
+       *count = 0;
+       detect_status = 0;
+       flags = COMMAND_LINE_SEPARATOR_SPACE;
+       flags |= COMMAND_LINE_SIGIL_DASH | COMMAND_LINE_SIGIL_DOUBLE_DASH;
+
+       settings = (rdpSettings*) malloc(sizeof(rdpSettings));
+       ZeroMemory(settings, sizeof(rdpSettings));
+
+       CommandLineClearArgumentsA(old_args);
+       status = CommandLineParseArgumentsA(argc, (const char**) argv, old_args, flags, settings,
+                       freerdp_client_old_command_line_pre_filter, NULL);
+
+       arg = old_args;
+
+       do
+       {
+               if (!(arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT))
+                       continue;
+
+               CommandLineSwitchStart(arg)
+
+               CommandLineSwitchCase(arg, "a")
+               {
+                       if ((strcmp(arg->Value, "8") == 0) ||
+                               (strcmp(arg->Value, "15") == 0) || (strcmp(arg->Value, "16") == 0) ||
+                               (strcmp(arg->Value, "24") == 0) || (strcmp(arg->Value, "32") == 0))
+                       {
+                               detect_status = 1;
+                       }
+
+               }
+               CommandLineSwitchDefault(arg)
+               {
+
+               }
+
+               CommandLineSwitchEnd(arg)
+
+               (*count)++;
+       }
+       while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
+
+       if ((status <= COMMAND_LINE_ERROR) && (status >= COMMAND_LINE_ERROR_LAST))
+               detect_status = -1;
+
+       if (detect_status == 0)
+       {
+               if (settings->ServerHostname)
+                       detect_status = 1;
+       }
+
+       free(settings);
+
+       return detect_status;
+}
+
+int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSettings* settings)
+{
+       char* p;
+       char* str;
+       int status;
+       DWORD flags;
+       COMMAND_LINE_ARGUMENT_A* arg;
+
+       freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0);
+
+       flags = COMMAND_LINE_SEPARATOR_SPACE;
+       flags |= COMMAND_LINE_SIGIL_DASH | COMMAND_LINE_SIGIL_DOUBLE_DASH;
+       flags |= COMMAND_LINE_SIGIL_ENABLE_DISABLE;
+
+       status = CommandLineParseArgumentsA(argc, (const char**) argv, old_args, flags, settings,
+                       freerdp_client_old_command_line_pre_filter, freerdp_client_old_command_line_post_filter);
+
+       if (status == COMMAND_LINE_STATUS_PRINT_HELP)
+       {
+               freerdp_client_print_command_line_help(argc, argv);
+               return COMMAND_LINE_STATUS_PRINT_HELP;
+       }
+       else if (status == COMMAND_LINE_STATUS_PRINT_VERSION)
+       {
+               freerdp_client_print_version();
+               return COMMAND_LINE_STATUS_PRINT_VERSION;
+       }
+       else if (status == COMMAND_LINE_STATUS_PRINT)
+       {
+               return COMMAND_LINE_STATUS_PRINT;
+       }
+
+       arg = old_args;
+
+       do
+       {
+               if (!(arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT))
+                       continue;
+
+               CommandLineSwitchStart(arg)
+
+               CommandLineSwitchCase(arg, "0")
+               {
+                       settings->ConsoleSession = TRUE;
+                       printf("-0 -> --admin\n");
+               }
+               CommandLineSwitchCase(arg, "a")
+               {
+                       settings->ColorDepth = atoi(arg->Value);
+                       printf("-a %s -> --bpp %s\n", arg->Value, arg->Value);
+               }
+               CommandLineSwitchCase(arg, "c")
+               {
+                       settings->ShellWorkingDirectory = _strdup(arg->Value);
+                       printf("-c %s -> --shell-dir %s\n", arg->Value, arg->Value);
+               }
+               CommandLineSwitchCase(arg, "D")
+               {
+                       settings->Decorations = FALSE;
+                       printf("-D -> --disable-decorations\n");
+               }
+               CommandLineSwitchCase(arg, "T")
+               {
+                       settings->WindowTitle = _strdup(arg->Value);
+                       printf("-T %s -> --title %s\n", arg->Value, arg->Value);
+               }
+               CommandLineSwitchCase(arg, "d")
+               {
+                       settings->Domain = _strdup(arg->Value);
+                       printf("-d %s -> -d %s\n", arg->Value, arg->Value);
+               }
+               CommandLineSwitchCase(arg, "f")
+               {
+                       settings->Fullscreen = TRUE;
+                       printf("-f -> -f\n");
+               }
+               CommandLineSwitchCase(arg, "g")
+               {
+                       str = _strdup(arg->Value);
+
+                       p = strchr(str, 'x');
+
+                       if (p)
+                       {
+                               *p = '\0';
+                               settings->DesktopWidth = atoi(str);
+                               settings->DesktopHeight = atoi(&p[1]);
+                       }
+
+                       free(str);
+
+                       printf("-g %s -> --size %s or -w %d -h %d\n", arg->Value, arg->Value,
+                                       settings->DesktopWidth, settings->DesktopHeight);
+               }
+               CommandLineSwitchCase(arg, "k")
+               {
+                       sscanf(arg->Value, "%X", &(settings->KeyboardLayout));
+                       printf("-k %s -> --kbd %s\n", arg->Value, arg->Value);
+               }
+               CommandLineSwitchCase(arg, "K")
+               {
+                       settings->GrabKeyboard = FALSE;
+                       printf("-K -> --disable-grab-keyboard\n");
+               }
+               CommandLineSwitchCase(arg, "n")
+               {
+                       settings->ClientHostname = _strdup(arg->Value);
+               }
+               CommandLineSwitchCase(arg, "o")
+               {
+                       settings->RemoteConsoleAudio = TRUE;
+                       printf("-o -> --audio-mode 1\n");
+               }
+               CommandLineSwitchCase(arg, "p")
+               {
+                       settings->Password = _strdup(arg->Value);
+                       printf("-p %s -> -p %s\n", arg->Value, arg->Value);
+               }
+               CommandLineSwitchCase(arg, "s")
+               {
+                       settings->AlternateShell = _strdup(arg->Value);
+                       printf("-s %s -> --shell %s\n", arg->Value, arg->Value);
+               }
+               CommandLineSwitchCase(arg, "t")
+               {
+                       settings->ServerPort = atoi(arg->Value);
+                       printf("-t %s -> --port %s\n", arg->Value, arg->Value);
+               }
+               CommandLineSwitchCase(arg, "u")
+               {
+                       settings->Username = _strdup(arg->Value);
+                       printf("-u %s -> -u %s\n", arg->Value, arg->Value);
+               }
+               CommandLineSwitchCase(arg, "x")
+               {
+                       int type;
+                       char* pEnd;
+
+                       type = strtol(arg->Value, &pEnd, 16);
+
+                       if (type == 0)
+                       {
+                               type = CONNECTION_TYPE_LAN;
+
+                               if (_stricmp(arg->Value, "m") == 0)
+                                       type = CONNECTION_TYPE_MODEM;
+                               else if (_stricmp(arg->Value, "b") == 0)
+                                       type = CONNECTION_TYPE_BROADBAND_HIGH;
+                               else if (_stricmp(arg->Value, "l") == 0)
+                                       type = CONNECTION_TYPE_LAN;
+
+                               freerdp_set_connection_type(settings, type);
+                       }
+                       else
+                       {
+                               settings->PerformanceFlags = type;
+                       }
+
+                       printf("-x %s -> --network ", arg->Value);
+
+                       if (type == CONNECTION_TYPE_MODEM)
+                               printf("modem");
+                       else if (CONNECTION_TYPE_BROADBAND_HIGH)
+                               printf("broadband");
+                       else if (CONNECTION_TYPE_LAN)
+                               printf("lan");
+
+                       printf("\n");
+               }
+               CommandLineSwitchCase(arg, "X")
+               {
+                       settings->ParentWindowId = strtol(arg->Value, NULL, 0);
+                       printf("-X %s -> --parent-window %s\n", arg->Value, arg->Value);
+               }
+               CommandLineSwitchCase(arg, "z")
+               {
+                       settings->CompressionEnabled = TRUE;
+                       printf("-z -> --compression\n");
+               }
+               CommandLineSwitchCase(arg, "app")
+               {
+                       settings->RemoteApplicationMode = TRUE;
+                       printf("--app -> --app + program name or alias\n");
+               }
+               CommandLineSwitchCase(arg, "ext")
+               {
+
+               }
+               CommandLineSwitchCase(arg, "no-auth")
+               {
+                       settings->Authentication = FALSE;
+                       printf("--no-auth -> --disable-authentication\n");
+               }
+               CommandLineSwitchCase(arg, "authonly")
+               {
+                       settings->AuthenticationOnly = TRUE;
+               }
+               CommandLineSwitchCase(arg, "from-stdin")
+               {
+                       settings->CredentialsFromStdin = TRUE;
+               }
+               CommandLineSwitchCase(arg, "no-fastpath")
+               {
+                       settings->FastPathInput = FALSE;
+                       settings->FastPathOutput = FALSE;
+                       printf("--no-fastpath -> --disable-fast-path\n");
+               }
+               CommandLineSwitchCase(arg, "no-motion")
+               {
+                       settings->MouseMotion = FALSE;
+                       printf("--no-motion -> --disable-mouse-motion\n");
+               }
+               CommandLineSwitchCase(arg, "gdi")
+               {
+                       if (strcmp(arg->Value, "sw") == 0)
+                               settings->SoftwareGdi = TRUE;
+                       else if (strcmp(arg->Value, "hw") == 0)
+                               settings->SoftwareGdi = FALSE;
+
+                       printf("--gdi %s -> --gdi %s\n", arg->Value, arg->Value);
+               }
+               CommandLineSwitchCase(arg, "no-osb")
+               {
+                       settings->OffscreenSupportLevel = FALSE;
+                       printf("--no-osb -> --disable-offscreen-cache\n");
+               }
+               CommandLineSwitchCase(arg, "no-bmp-cache")
+               {
+                       settings->BitmapCacheEnabled = FALSE;
+                       printf("--no-bmp-cache -> --disable-bitmap-cache\n");
+               }
+               CommandLineSwitchCase(arg, "plugin")
+               {
+                       printf("--plugin -> -a, --vc, --dvc and channel-specific options\n");
+               }
+               CommandLineSwitchCase(arg, "rfx")
+               {
+                       settings->RemoteFxCodec = TRUE;
+                       printf("--rfx -> --rfx\n");
+               }
+               CommandLineSwitchCase(arg, "rfx-mode")
+               {
+                       if (arg->Value[0] == 'v')
+                               settings->RemoteFxCodecMode = 0x00;
+                       else if (arg->Value[0] == 'i')
+                               settings->RemoteFxCodecMode = 0x02;
+                       printf("--rfx-mode -> --rfx-mode\n");
+               }
+               CommandLineSwitchCase(arg, "nsc")
+               {
+                       settings->NSCodec = TRUE;
+                       printf("--nsc -> --nsc\n");
+               }
+               CommandLineSwitchCase(arg, "disable-wallpaper")
+               {
+                       settings->DisableWallpaper = TRUE;
+                       printf("--disable-wallpaper -> --disable-wallpaper\n");
+               }
+               CommandLineSwitchCase(arg, "composition")
+               {
+                       settings->AllowDesktopComposition = TRUE;
+                       printf("--composition -> --enable-composition\n");
+               }
+               CommandLineSwitchCase(arg, "disable-full-window-drag")
+               {
+                       settings->DisableFullWindowDrag = TRUE;
+                       printf("--disable-full-window-drag -> --disable-window-drag\n");
+               }
+               CommandLineSwitchCase(arg, "disable-menu-animations")
+               {
+                       settings->DisableMenuAnims = TRUE;
+                       printf("--disable-menu-animations -> --disable-menu-anims\n");
+               }
+               CommandLineSwitchCase(arg, "disable-theming")
+               {
+                       settings->DisableThemes = TRUE;
+                       printf("--disable-theming -> --disable-themes\n");
+               }
+               CommandLineSwitchCase(arg, "ntlm")
+               {
+
+               }
+               CommandLineSwitchCase(arg, "ignore-certificate")
+               {
+                       settings->IgnoreCertificate = TRUE;
+                       printf("--ignore-certificate -> --cert-ignore\n");
+               }
+               CommandLineSwitchCase(arg, "sec")
+               {
+                       if (strncmp("rdp", arg->Value, 1) == 0) /* Standard RDP */
+                       {
+                               settings->RdpSecurity = TRUE;
+                               settings->TlsSecurity = FALSE;
+                               settings->NlaSecurity = FALSE;
+                               settings->DisableEncryption = FALSE;
+                               settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
+                               settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
+                       }
+                       else if (strncmp("tls", arg->Value, 1) == 0) /* TLS */
+                       {
+                               settings->RdpSecurity = FALSE;
+                               settings->TlsSecurity = TRUE;
+                               settings->NlaSecurity = FALSE;
+                       }
+                       else if (strncmp("nla", arg->Value, 1) == 0) /* NLA */
+                       {
+                               settings->RdpSecurity = FALSE;
+                               settings->TlsSecurity = FALSE;
+                               settings->NlaSecurity = TRUE;
+                       }
+
+                       printf("--sec %s -> --sec %s\n", arg->Value, arg->Value);
+               }
+               CommandLineSwitchCase(arg, "no-rdp")
+               {
+                       settings->RdpSecurity = FALSE;
+                       printf("--no-rdp -> --disable-sec-rdp\n");
+               }
+               CommandLineSwitchCase(arg, "no-tls")
+               {
+                       settings->TlsSecurity = FALSE;
+                       printf("--no-tls -> --disable-sec-tls\n");
+               }
+               CommandLineSwitchCase(arg, "no-nla")
+               {
+                       settings->NlaSecurity = FALSE;
+                       printf("--no-nla -> --disable-sec-nla\n");
+               }
+               CommandLineSwitchCase(arg, "secure-checksum")
+               {
+                       settings->SaltedChecksum = TRUE;
+               }
+               CommandLineSwitchDefault(arg)
+               {
+
+               }
+
+               CommandLineSwitchEnd(arg)
+       }
+       while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
+
+       printf("%s -> -v %s", settings->ServerHostname, settings->ServerHostname);
+
+       if (settings->ServerPort != 3389)
+               printf(" --port %d", settings->ServerPort);
+
+       printf("\n");
+
+       return 1;
+}
diff --git a/client/common/compatibility.h b/client/common/compatibility.h
new file mode 100644 (file)
index 0000000..5d2077d
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Client Compatibility
+ *
+ * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FREERDP_CLIENT_COMPATIBILITY_H
+#define FREERDP_CLIENT_COMPATIBILITY_H
+
+#include <freerdp/api.h>
+#include <freerdp/freerdp.h>
+
+int freerdp_detect_old_command_line_syntax(int argc, char** argv, int* count);
+int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSettings* settings);
+
+#endif /* FREERDP_CLIENT_COMPATIBILITY */
+
index 141bc0f..944c731 100644 (file)
@@ -25,6 +25,8 @@
 
 FREERDP_API int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettings* settings);
 FREERDP_API int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings);
+
+FREERDP_API int freerdp_client_print_version();
 FREERDP_API int freerdp_client_print_command_line_help(int argc, char** argv);
 
 FREERDP_API int freerdp_parse_username(char* username, char** user, char** domain);
index 4f81bf0..6a3b8c6 100644 (file)
 
 /* Command-Line Parsing Error Codes */
 
+#define COMMAND_LINE_ERROR                     -1000
 #define COMMAND_LINE_ERROR_NO_KEYWORD          -1001
 #define COMMAND_LINE_ERROR_UNEXPECTED_VALUE    -1002
 #define COMMAND_LINE_ERROR_MISSING_VALUE       -1003
 #define COMMAND_LINE_ERROR_MISSING_ARGUMENT    -1004
 #define COMMAND_LINE_ERROR_UNEXPECTED_SIGIL    -1005
+#define COMMAND_LINE_ERROR_LAST                        -1006
 
 /* Command-Line Parsing Status Codes */
 
@@ -115,8 +117,8 @@ struct _COMMAND_LINE_ARGUMENT_W
 #define COMMAND_LINE_ARGUMENT  COMMAND_LINE_ARGUMENT_A
 #endif
 
-typedef int (*COMMAND_LINE_PRE_FILTER_FN_A)(void* context, int index, LPCSTR arg);
-typedef int (*COMMAND_LINE_PRE_FILTER_FN_W)(void* context, int index, LPCWSTR arg);
+typedef int (*COMMAND_LINE_PRE_FILTER_FN_A)(void* context, int index, int argc, LPCSTR* argv);
+typedef int (*COMMAND_LINE_PRE_FILTER_FN_W)(void* context, int index, int argc, LPCWSTR* argv);
 
 typedef int (*COMMAND_LINE_POST_FILTER_FN_A)(void* context, COMMAND_LINE_ARGUMENT_A* arg);
 typedef int (*COMMAND_LINE_POST_FILTER_FN_W)(void* context, COMMAND_LINE_ARGUMENT_W* arg);
index 51be3b2..d621b21 100644 (file)
@@ -115,7 +115,10 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
                index = i;
 
                if (preFilter)
-                       preFilter(context, i, argv[i]);
+               {
+                       if (preFilter(context, i, argc, argv) < 0)
+                               return COMMAND_LINE_ERROR;
+               }
 
                sigil_index = 0;
                sigil_length = 0;