libfreerdp-utils/args: add argument parser.
This commit is contained in:
parent
de5c0c8e25
commit
2beb49725f
@ -1,6 +1,8 @@
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#define FREERDP_VERSION_FULL "${FREERDP_VERSION_FULL}"
|
||||
|
||||
/* Include files */
|
||||
#cmakedefine HAVE_SYS_PARAM_H
|
||||
#cmakedefine HAVE_SYS_SOCKET_H
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <freerdp/utils/semaphore.h>
|
||||
#include <freerdp/utils/load_plugin.h>
|
||||
#include <freerdp/utils/wait_obj.h>
|
||||
#include <freerdp/utils/args.h>
|
||||
|
||||
#include "test_utils.h"
|
||||
|
||||
@ -46,6 +47,7 @@ int add_utils_suite(void)
|
||||
add_test_function(semaphore);
|
||||
add_test_function(load_plugin);
|
||||
add_test_function(wait_obj);
|
||||
add_test_function(args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -100,3 +102,55 @@ void test_wait_obj(void)
|
||||
|
||||
wait_obj_free(wo);
|
||||
}
|
||||
|
||||
static int process_plugin_args(rdpSettings* settings, const char* name,
|
||||
FRDP_PLUGIN_DATA* plugin_data, void* user_data)
|
||||
{
|
||||
/*printf("load plugin: %s\n", name);*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int process_ui_args(rdpSettings* settings, const char* opt,
|
||||
const char* val, void* user_data)
|
||||
{
|
||||
/*printf("ui arg: %s %s\n", opt, val);*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
void test_args(void)
|
||||
{
|
||||
char* argv_c[] =
|
||||
{
|
||||
"-a", "8", "-u", "testuser", "-d", "testdomain", "-g", "640x480", "address1:3389",
|
||||
"-a", "16", "-u", "testuser", "-d", "testdomain", "-g", "1280x960", "address2:3390"
|
||||
};
|
||||
char** argv = argv_c;
|
||||
int argc = sizeof(argv_c) / sizeof(char*);
|
||||
int i;
|
||||
int c;
|
||||
rdpSettings* settings;
|
||||
|
||||
i = 0;
|
||||
while (argc > 0)
|
||||
{
|
||||
settings = settings_new();
|
||||
|
||||
i++;
|
||||
c = freerdp_parse_args(settings, argc, argv, process_plugin_args, NULL, process_ui_args, NULL);
|
||||
CU_ASSERT(c > 0);
|
||||
if (c == 0)
|
||||
{
|
||||
settings_free(settings);
|
||||
break;
|
||||
}
|
||||
CU_ASSERT(settings->color_depth == i * 8);
|
||||
CU_ASSERT(settings->width == i * 640);
|
||||
CU_ASSERT(settings->height == i * 480);
|
||||
CU_ASSERT(settings->port == i + 3388);
|
||||
|
||||
settings_free(settings);
|
||||
argc -= c;
|
||||
argv += c;
|
||||
}
|
||||
CU_ASSERT(i == 2);
|
||||
}
|
||||
|
@ -27,3 +27,4 @@ void test_mutex(void);
|
||||
void test_semaphore(void);
|
||||
void test_load_plugin(void);
|
||||
void test_wait_obj(void);
|
||||
void test_args(void);
|
||||
|
38
include/freerdp/utils/args.h
Normal file
38
include/freerdp/utils/args.h
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol client.
|
||||
* Arguments Parsing
|
||||
*
|
||||
* Copyright 2011 Vic Lee
|
||||
*
|
||||
* 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 __ARGS_UTILS_H
|
||||
#define __ARGS_UTILS_H
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/settings.h>
|
||||
|
||||
/* Returns 1 if succeed, otherwise returns zero */
|
||||
typedef int (*ProcessPluginArgs) (rdpSettings* settings, const char* name,
|
||||
FRDP_PLUGIN_DATA* plugin_data, void* user_data);
|
||||
|
||||
/* Returns number of arguments processed (1 or 2), otherwise returns zero */
|
||||
typedef int (*ProcessUIArgs) (rdpSettings* settings, const char* opt,
|
||||
const char* val, void* user_data);
|
||||
|
||||
int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
|
||||
ProcessPluginArgs plugin_callback, void* plugin_user_data,
|
||||
ProcessUIArgs ui_callback, void* ui_user_data);
|
||||
|
||||
#endif /* __ARGS_UTILS_H */
|
@ -18,6 +18,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
set(FREERDP_UTILS_SRCS
|
||||
args.c
|
||||
blob.c
|
||||
event.c
|
||||
hexdump.c
|
||||
|
392
libfreerdp-utils/args.c
Normal file
392
libfreerdp-utils/args.c
Normal file
@ -0,0 +1,392 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol client.
|
||||
* Arguments Parsing
|
||||
*
|
||||
* Copyright 2009-2011 Jay Sorg
|
||||
* Copyright 2011 Vic Lee
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/args.h>
|
||||
|
||||
#define MAX_PLUGIN_DATA 20
|
||||
|
||||
/**
|
||||
* Parse command-line arguments and update rdpSettings members accordingly.
|
||||
* @param settings pointer to rdpSettings struct to be updated.
|
||||
* @param argc number of arguments available.
|
||||
* @param argv string array of the arguments.
|
||||
* @param plugin_callback function to be called when a plugin needs to be loaded.
|
||||
* @param plugin_user_data pointer to be passed to the plugin_callback function.
|
||||
* @param ui_callback function to be called when a UI-specific argument is being processed.
|
||||
* @param ui_user_data pointer to be passed to the ui_callback function.
|
||||
* @return number of arguments that has been parsed, or 0 if error occurred.
|
||||
*/
|
||||
int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
|
||||
ProcessPluginArgs plugin_callback, void* plugin_user_data,
|
||||
ProcessUIArgs ui_callback, void* ui_user_data)
|
||||
{
|
||||
int index = 0;
|
||||
int num_extensions = 0;
|
||||
int i, j;
|
||||
int t;
|
||||
char* p;
|
||||
FRDP_PLUGIN_DATA plugin_data[MAX_PLUGIN_DATA + 1];
|
||||
|
||||
while (index < argc)
|
||||
{
|
||||
if (strcmp("-a", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing color depth\n");
|
||||
return 0;
|
||||
}
|
||||
settings->color_depth = atoi(argv[index]);
|
||||
}
|
||||
else if (strcmp("-u", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing username\n");
|
||||
return 0;
|
||||
}
|
||||
settings->username = (uint8*)xstrdup(argv[index]);
|
||||
}
|
||||
else if (strcmp("-p", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing password\n");
|
||||
return 0;
|
||||
}
|
||||
settings->password = (uint8*)xstrdup(argv[index]);
|
||||
settings->autologon = 1;
|
||||
|
||||
/*
|
||||
* Overwrite original password which could be revealed by a simple "ps aux" command.
|
||||
* This approach won't hide the password length, but it is better than nothing.
|
||||
*/
|
||||
|
||||
memset(argv[index], '*', strlen(argv[index]));
|
||||
}
|
||||
else if (strcmp("-d", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing domain\n");
|
||||
return 0;
|
||||
}
|
||||
settings->domain = (uint8*)xstrdup(argv[index]);
|
||||
}
|
||||
else if (strcmp("-s", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing shell\n");
|
||||
return 0;
|
||||
}
|
||||
settings->shell = (uint8*)xstrdup(argv[index]);
|
||||
}
|
||||
else if (strcmp("-c", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing directory\n");
|
||||
return 0;
|
||||
}
|
||||
settings->directory = (uint8*)xstrdup(argv[index]);
|
||||
}
|
||||
else if (strcmp("-g", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing width\n");
|
||||
return 0;
|
||||
}
|
||||
settings->width = strtol(argv[index], &p, 10);
|
||||
if (*p == 'x')
|
||||
{
|
||||
settings->height = strtol(p + 1, &p, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_callback(settings, "-g", p, ui_user_data);
|
||||
}
|
||||
}
|
||||
else if (strcmp("-t", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing port number\n");
|
||||
return 0;
|
||||
}
|
||||
settings->port = atoi(argv[index]);
|
||||
}
|
||||
else if (strcmp("-n", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing client hostname\n");
|
||||
return 0;
|
||||
}
|
||||
strncpy(settings->client_hostname, argv[index], sizeof(settings->client_hostname) - 1);
|
||||
settings->client_hostname[sizeof(settings->client_hostname) - 1] = 0;
|
||||
}
|
||||
else if (strcmp("-o", argv[index]) == 0)
|
||||
{
|
||||
settings->console_audio = 1;
|
||||
}
|
||||
else if (strcmp("-0", argv[index]) == 0)
|
||||
{
|
||||
settings->console_session = 1;
|
||||
}
|
||||
else if (strcmp("-z", argv[index]) == 0)
|
||||
{
|
||||
settings->compression = 1;
|
||||
}
|
||||
else if (strcmp("--no-osb", argv[index]) == 0)
|
||||
{
|
||||
settings->off_screen_bitmaps = 0;
|
||||
}
|
||||
else if (strcmp("--rfx", argv[index]) == 0)
|
||||
{
|
||||
settings->rfx_flags = 1;
|
||||
settings->ui_decode_flags = 1;
|
||||
settings->use_frame_ack = 0;
|
||||
settings->color_depth = 32;
|
||||
settings->performance_flags = PERF_FLAG_NONE;
|
||||
}
|
||||
else if (strcmp("-m", argv[index]) == 0)
|
||||
{
|
||||
settings->mouse_motion = 0;
|
||||
}
|
||||
else if (strcmp("--app", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing application name\n");
|
||||
return 0;
|
||||
}
|
||||
strncpy(settings->app_name, argv[index], sizeof(settings->app_name) - 1);
|
||||
settings->app_name[sizeof(settings->app_name) - 1] = 0;
|
||||
settings->remote_app = 1;
|
||||
}
|
||||
else if (strcmp("-x", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing performance flag\n");
|
||||
return 0;
|
||||
}
|
||||
if (argv[index][0] == 'm') /* modem */
|
||||
{
|
||||
settings->performance_flags = PERF_DISABLE_WALLPAPER |
|
||||
PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS |
|
||||
PERF_DISABLE_THEMING;
|
||||
}
|
||||
else if (argv[index][0] == 'b') /* broadband */
|
||||
{
|
||||
settings->performance_flags = PERF_DISABLE_WALLPAPER;
|
||||
}
|
||||
else if (argv[index][0] == 'l') /* lan */
|
||||
{
|
||||
settings->performance_flags = PERF_FLAG_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
settings->performance_flags = strtol(argv[index], 0, 16);
|
||||
}
|
||||
}
|
||||
else if (strcmp("--no-rdp", argv[index]) == 0)
|
||||
{
|
||||
settings->rdp_security = 0;
|
||||
}
|
||||
else if (strcmp("--no-tls", argv[index]) == 0)
|
||||
{
|
||||
settings->tls_security = 0;
|
||||
}
|
||||
else if (strcmp("--no-nla", argv[index]) == 0)
|
||||
{
|
||||
settings->nla_security = 0;
|
||||
}
|
||||
else if (strcmp("--sec", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing protocol security\n");
|
||||
return 0;
|
||||
}
|
||||
if (strncmp("rdp", argv[index], 1) == 0) /* Standard RDP */
|
||||
{
|
||||
settings->rdp_security = 1;
|
||||
settings->tls_security = 0;
|
||||
settings->nla_security = 0;
|
||||
}
|
||||
else if (strncmp("tls", argv[index], 1) == 0) /* TLS */
|
||||
{
|
||||
settings->rdp_security = 0;
|
||||
settings->tls_security = 1;
|
||||
settings->nla_security = 0;
|
||||
}
|
||||
else if (strncmp("nla", argv[index], 1) == 0) /* NLA */
|
||||
{
|
||||
settings->rdp_security = 0;
|
||||
settings->tls_security = 0;
|
||||
settings->nla_security = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("unknown protocol security\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (strcmp("--plugin", argv[index]) == 0)
|
||||
{
|
||||
t = index;
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing plugin name\n");
|
||||
return 0;
|
||||
}
|
||||
memset(plugin_data, 0, sizeof(plugin_data));
|
||||
if (index < argc - 1 && strcmp("--data", argv[index + 1]) == 0)
|
||||
{
|
||||
index += 2;
|
||||
i = 0;
|
||||
while (index < argc && strcmp("--", argv[index]) != 0 && i < MAX_PLUGIN_DATA)
|
||||
{
|
||||
plugin_data[i].size = sizeof(FRDP_PLUGIN_DATA);
|
||||
for (j = 0, p = argv[index]; j < 4 && p != NULL; j++)
|
||||
{
|
||||
if (*p == '\'')
|
||||
{
|
||||
plugin_data[i].data[j] = p + 1;
|
||||
p = strchr(p + 1, '\'');
|
||||
if (p)
|
||||
*p++ = 0;
|
||||
}
|
||||
else
|
||||
plugin_data[i].data[j] = p;
|
||||
|
||||
p = strchr(p, ':');
|
||||
if (p != NULL)
|
||||
*p++ = 0;
|
||||
}
|
||||
index++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (!plugin_callback(settings, argv[t], plugin_data, plugin_user_data))
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp("--ext", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing extension name\n");
|
||||
return 0;
|
||||
}
|
||||
if (num_extensions >= sizeof(settings->extensions) / sizeof(struct rdp_ext_set))
|
||||
{
|
||||
printf("maximum extensions reached\n");
|
||||
return 0;
|
||||
}
|
||||
snprintf(settings->extensions[num_extensions].name,
|
||||
sizeof(settings->extensions[num_extensions].name),
|
||||
"%s", argv[index]);
|
||||
settings->extensions[num_extensions].data = NULL;
|
||||
if (index < argc - 1 && strcmp("--data", argv[index + 1]) == 0)
|
||||
{
|
||||
index += 2;
|
||||
settings->extensions[num_extensions].data = argv[index];
|
||||
i = 0;
|
||||
while (index < argc && strcmp("--", argv[index]) != 0)
|
||||
{
|
||||
index++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
num_extensions++;
|
||||
}
|
||||
else if (strcmp("--version", argv[index]) == 0)
|
||||
{
|
||||
printf("This is FreeRDP version %s\n", FREERDP_VERSION_FULL);
|
||||
return 0;
|
||||
}
|
||||
else if (argv[index][0] != '-')
|
||||
{
|
||||
if (argv[index][0] == '[' && (p = strchr(argv[index], ']'))
|
||||
&& (p[1] == 0 || (p[1] == ':' && !strchr(p + 2, ':'))))
|
||||
{
|
||||
/* Either "[...]" or "[...]:..." with at most one : after the brackets */
|
||||
settings->hostname = (uint8*)xstrdup(argv[index] + 1);
|
||||
if ((p = strchr((char*)settings->hostname, ']')))
|
||||
{
|
||||
*p = 0;
|
||||
if (p[1] == ':')
|
||||
settings->port = atoi(p + 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Port number is cut off and used if exactly one : in the string */
|
||||
settings->hostname = (uint8*)xstrdup(argv[index]);
|
||||
if ((p = strchr((char*)settings->hostname, ':')) && !strchr(p + 1, ':'))
|
||||
{
|
||||
*p = 0;
|
||||
settings->port = atoi(p + 1);
|
||||
}
|
||||
}
|
||||
/* server is the last argument for the current session. arguments
|
||||
followed will be parsed for the next session. */
|
||||
index++;
|
||||
|
||||
return index;
|
||||
}
|
||||
else
|
||||
{
|
||||
t = ui_callback(settings, argv[index], (index + 1 < argc && argv[index + 1][0] != '-' ?
|
||||
argv[index + 1] : NULL), ui_user_data);
|
||||
if (t == 0)
|
||||
{
|
||||
printf("invalid option: %s\n", argv[index]);
|
||||
return 0;
|
||||
}
|
||||
index += t - 1;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
printf("missing server name\n");
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user