client: Utilize l_parse_args

This commit is contained in:
Denis Kenzior 2018-07-27 14:41:30 -05:00
parent 215162a49e
commit 67e590cfeb
12 changed files with 134 additions and 251 deletions

View File

@ -219,7 +219,8 @@ static const struct proxy_interface *get_adapter_proxy_by_name(
return proxy;
}
static enum cmd_status cmd_list(const char *adapter_name, char *args)
static enum cmd_status cmd_list(const char *adapter_name,
char **argv, int argc)
{
display_table_header("Adapters", MARGIN "%-*s%-*s%-*s%-*s", 19, "Name",
10, "Powered", 20, "Vendor", 20, "Model");
@ -231,7 +232,8 @@ static enum cmd_status cmd_list(const char *adapter_name, char *args)
return CMD_STATUS_OK;
}
static enum cmd_status cmd_show(const char *adapter_name, char *args)
static enum cmd_status cmd_show(const char *adapter_name,
char **argv, int argc)
{
const struct proxy_interface *proxy =
get_adapter_proxy_by_name(adapter_name);
@ -250,29 +252,21 @@ static void property_set_callback(struct l_dbus_message *message,
dbus_message_has_error(message);
}
static enum cmd_status cmd_set_property(const char *adapter_name, char *args)
static enum cmd_status cmd_set_property(const char *adapter_name,
char **argv, int argc)
{
char *name;
char *value_str;
const struct proxy_interface *proxy =
get_adapter_proxy_by_name(adapter_name);
if (!proxy)
return CMD_STATUS_INVALID_VALUE;
if (!properties_parse_args(args, &name, &value_str))
if (argc != 2)
return CMD_STATUS_INVALID_ARGS;
if (!proxy_property_set(proxy, name, value_str,
property_set_callback)) {
l_free(name);
l_free(value_str);
if (!proxy_property_set(proxy, argv[0], argv[1],
property_set_callback))
return CMD_STATUS_INVALID_VALUE;
}
l_free(name);
l_free(value_str);
return CMD_STATUS_OK;
}

View File

@ -33,14 +33,16 @@
static struct l_queue *command_families;
static enum cmd_status cmd_version(const char *entity, char *arg)
static enum cmd_status cmd_version(const char *entity,
char **argv, int argc)
{
display("IWD version %s\n", VERSION);
return CMD_STATUS_OK;
}
static enum cmd_status cmd_quit(const char *entity, char *arg)
static enum cmd_status cmd_quit(const char *entity,
char **argv, int argc)
{
display_quit();
@ -323,13 +325,14 @@ char *command_entity_arg_completion(const char *text, int state,
}
static void execute_cmd(const char *family, const char *entity,
const struct command *cmd, char *args)
const struct command *cmd,
char **argv, int argc)
{
enum cmd_status status;
display_refresh_set_cmd(family, entity, cmd, args);
display_refresh_set_cmd(family, entity, cmd, argv, argc);
status = cmd->function(entity, args);
status = cmd->function(entity, argv, argc);
if (status != CMD_STATUS_OK)
goto error;
@ -365,7 +368,8 @@ error:
}
static bool match_cmd(const char *family, const char *entity, const char *cmd,
char *args, const struct command *command_list)
char **argv, int argc,
const struct command *command_list)
{
size_t i;
@ -374,50 +378,40 @@ static bool match_cmd(const char *family, const char *entity, const char *cmd,
continue;
if (!command_list[i].function)
goto nomatch;
return false;
execute_cmd(family, entity, &command_list[i], args);
execute_cmd(family, entity, &command_list[i], argv, argc);
return true;
}
nomatch:
return false;
}
static bool match_cmd_family(const char *cmd_family, char *arg)
static bool match_cmd_family(char **argv, int argc)
{
const struct l_queue_entry *entry;
const char *arg1;
const char *arg2;
if (argc < 2)
return false;
for (entry = l_queue_get_entries(command_families); entry;
entry = entry->next) {
const struct command_family *family = entry->data;
if (strcmp(family->name, cmd_family))
if (strcmp(family->name, argv[0]))
continue;
arg1 = strtok_r(NULL, " ", &arg);
if (!arg1)
goto nomatch;
if (match_cmd(family->name, NULL, arg1, arg,
family->command_list))
return true;
arg2 = strtok_r(NULL, " ", &arg);
if (!arg2)
goto nomatch;
if (!match_cmd(family->name, arg1, arg2, arg,
family->command_list))
goto nomatch;
return true;
if (argc >= 3)
return match_cmd(family->name, argv[1], argv[2],
argv + 3, argc - 3,
family->command_list);
else
return match_cmd(family->name, NULL, argv[1],
argv + 2, argc - 2,
family->command_list);
}
nomatch:
return false;
}
@ -447,24 +441,20 @@ static void list_cmd_families(void)
}
}
void command_process_prompt(char *prompt)
void command_process_prompt(char **argv, int argc)
{
const char *cmd;
char *arg = NULL;
cmd = strtok_r(prompt, " ", &arg);
if (!cmd)
if (argc == 0)
return;
if (match_cmd_family(cmd, arg))
if (match_cmd_family(argv, argc))
return;
display_refresh_reset();
if (match_cmd(NULL, NULL, cmd, arg, command_list))
if (match_cmd(NULL, NULL, argv[0], argv + 1, argc - 1, command_list))
return;
if (strcmp(cmd, "help")) {
if (strcmp(argv[0], "help")) {
display("Invalid command\n");
return;
}

View File

@ -34,7 +34,8 @@ struct command {
const char *entity;
const char *cmd;
const char *arg;
enum cmd_status (*function)(const char *entity, char *arg);
enum cmd_status (*function)(const char *entity,
char **argv, int argc);
const char *desc;
const bool refreshable;
command_completion_func_t completion;
@ -54,7 +55,7 @@ char **command_completion(const char *text, int start, int end);
char *command_entity_arg_completion(const char *text, int state,
const struct command *command_list);
void command_process_prompt(char *prompt);
void command_process_prompt(char **argv, int argc);
void command_family_register(const struct command_family *family);
void command_family_unregister(const struct command_family *family);

View File

@ -607,7 +607,8 @@ static const struct proxy_interface *get_device_proxy_by_name(
return proxy;
}
static enum cmd_status cmd_show(const char *device_name, char *args)
static enum cmd_status cmd_show(const char *device_name,
char **argv, int argc)
{
const struct proxy_interface *proxy =
get_device_proxy_by_name(device_name);
@ -626,7 +627,8 @@ static void check_errors_method_callback(struct l_dbus_message *message,
dbus_message_has_error(message);
}
static enum cmd_status cmd_scan(const char *device_name, char *args)
static enum cmd_status cmd_scan(const char *device_name,
char **argv, int argc)
{
const struct proxy_interface *proxy =
get_device_proxy_by_name(device_name);
@ -640,7 +642,8 @@ static enum cmd_status cmd_scan(const char *device_name, char *args)
return CMD_STATUS_OK;
}
static enum cmd_status cmd_disconnect(const char *device_name, char *args)
static enum cmd_status cmd_disconnect(const char *device_name,
char **argv, int argc)
{
const struct proxy_interface *proxy =
get_device_proxy_by_name(device_name);
@ -654,7 +657,8 @@ static enum cmd_status cmd_disconnect(const char *device_name, char *args)
return CMD_STATUS_OK;
}
static enum cmd_status cmd_get_networks(const char *device_name, char *args)
static enum cmd_status cmd_get_networks(const char *device_name,
char **argv, int argc)
{
const struct proxy_interface *proxy =
get_device_proxy_by_name(device_name);
@ -662,10 +666,10 @@ static enum cmd_status cmd_get_networks(const char *device_name, char *args)
if (!proxy)
return CMD_STATUS_INVALID_ARGS;
if (!args)
if (!argc)
goto proceed;
if (!strcmp(args, RSSI_DBMS))
if (!strcmp(argv[0], RSSI_DBMS))
display_signal_as_dbms = true;
else
display_signal_as_dbms = false;
@ -677,7 +681,8 @@ proceed:
return CMD_STATUS_OK;
}
static enum cmd_status cmd_list(const char *device_name, char *args)
static enum cmd_status cmd_list(const char *device_name,
char **argv, int argc)
{
display_table_header("Devices", MARGIN "%-*s%-*s%-*s%-*s", 20, "Name",
20, "Address", 15, "State", 10, "Adapter");
@ -689,36 +694,29 @@ static enum cmd_status cmd_list(const char *device_name, char *args)
return CMD_STATUS_OK;
}
static enum cmd_status cmd_set_property(const char *device_name, char *args)
static enum cmd_status cmd_set_property(const char *device_name,
char **argv, int argc)
{
char *name;
char *value_str;
const struct proxy_interface *proxy =
get_device_proxy_by_name(device_name);
if (!proxy)
return CMD_STATUS_INVALID_VALUE;
if (!properties_parse_args(args, &name, &value_str))
if (argc != 2)
return CMD_STATUS_INVALID_ARGS;
if (!proxy_property_set(proxy, name, value_str,
check_errors_method_callback)) {
l_free(name);
l_free(value_str);
if (!proxy_property_set(proxy, argv[0], argv[1],
check_errors_method_callback))
return CMD_STATUS_INVALID_VALUE;
}
l_free(name);
l_free(value_str);
return CMD_STATUS_OK;
}
static enum cmd_status cmd_connect(const char *device_name, char *args)
static enum cmd_status cmd_connect(const char *device_name,
char **argv, int argc)
{
struct network_args *network_args;
struct network_args network_args;
struct l_queue *match;
const struct proxy_interface *network_proxy;
const struct proxy_interface *device_proxy =
@ -727,68 +725,53 @@ static enum cmd_status cmd_connect(const char *device_name, char *args)
if (!device_proxy)
return CMD_STATUS_INVALID_VALUE;
network_args = network_parse_args(args);
if (!network_args || !network_args->name) {
network_args_destroy(network_args);
if (argc < 1)
return CMD_STATUS_INVALID_ARGS;
}
match = network_match_by_device_and_args(device_proxy, network_args);
network_args.name = argv[0];
if (argc >= 2)
network_args.type = argv[1];
match = network_match_by_device_and_args(device_proxy, &network_args);
if (!match) {
display("Invalid network name '%s'\n", network_args->name);
network_args_destroy(network_args);
display("Invalid network name '%s'\n", network_args.name);
return CMD_STATUS_INVALID_VALUE;
}
if (l_queue_length(match) > 1) {
if (!network_args->type) {
if (!network_args.type) {
display("Provided network name is ambiguous. "
"Please specify security type.\n");
}
l_queue_destroy(match, NULL);
network_args_destroy(network_args);
return CMD_STATUS_INVALID_VALUE;
}
network_proxy = l_queue_pop_head(match);
l_queue_destroy(match, NULL);
network_args_destroy(network_args);
network_connect(network_proxy);
return CMD_STATUS_OK;
}
static enum cmd_status cmd_connect_hidden_network(const char *device_name,
char *args)
char **argv,
int argc)
{
struct network_args *network_args;
const struct proxy_interface *proxy =
get_device_proxy_by_name(device_name);
if (!proxy)
return CMD_STATUS_INVALID_VALUE;
network_args = network_parse_args(args);
if (!network_args || !network_args->name) {
network_args_destroy(network_args);
if (argc != 1)
return CMD_STATUS_INVALID_ARGS;
}
proxy_interface_method_call(proxy, "ConnectHiddenNetwork", "s",
check_errors_method_callback,
network_args->name);
network_args_destroy(network_args);
argv[0]);
return CMD_STATUS_OK;
}

View File

@ -47,7 +47,8 @@ static struct display_refresh {
char *family;
char *entity;
const struct command *cmd;
char *args;
char **argv;
int argc;
size_t undo_lines;
struct l_queue *redo_entries;
bool recording;
@ -135,8 +136,9 @@ void display_refresh_reset(void)
display_refresh.cmd = NULL;
l_free(display_refresh.args);
display_refresh.args = NULL;
l_strfreev(display_refresh.argv);
display_refresh.argv = NULL;
display_refresh.argc = 0;
display_refresh.undo_lines = 0;
display_refresh.recording = false;
@ -145,8 +147,11 @@ void display_refresh_reset(void)
}
void display_refresh_set_cmd(const char *family, const char *entity,
const struct command *cmd, char *args)
const struct command *cmd,
char **argv, int argc)
{
int i;
if (cmd->refreshable) {
l_free(display_refresh.family);
display_refresh.family = l_strdup(family);
@ -156,8 +161,12 @@ void display_refresh_set_cmd(const char *family, const char *entity,
display_refresh.cmd = cmd;
l_free(display_refresh.args);
display_refresh.args = l_strdup(args);
l_strfreev(display_refresh.argv);
display_refresh.argc = argc;
display_refresh.argv = l_new(char *, argc + 1);
for (i = 0; i < argc; i++)
display_refresh.argv[i] = argv[i];
l_queue_clear(display_refresh.redo_entries, l_free);
@ -168,8 +177,16 @@ void display_refresh_set_cmd(const char *family, const char *entity,
}
if (display_refresh.family && !strcmp(display_refresh.family, family)) {
char *prompt =
l_strdup_printf(IWD_PROMPT"%s%s%s %s %s\n",
struct l_string *buf = l_string_new(128);
L_AUTO_FREE_VAR(char *, args);
char *prompt;
for (i = 0; i < argc; i++)
l_string_append_printf(buf, "'%s' ", argv[i]);
args = l_string_unwrap(buf);
prompt = l_strdup_printf(IWD_PROMPT"%s%s%s %s %s\n",
family ? : "",
entity ? " " : "", entity ? : "",
cmd->cmd ? : "", args ? : "");
@ -196,7 +213,8 @@ static void timeout_callback(struct l_timeout *timeout, void *user_data)
display_refresh.recording = false;
display_refresh.cmd->function(display_refresh.entity,
display_refresh.args);
display_refresh.argv,
display_refresh.argc);
}
void display_refresh_timeout_set(void)
@ -408,6 +426,9 @@ static void reset_masked_input(void)
static void readline_callback(char *prompt)
{
char **argv;
int argc;
HIST_ENTRY *previous_prompt;
if (!prompt) {
@ -432,7 +453,13 @@ static void readline_callback(char *prompt)
add_history(prompt);
}
command_process_prompt(prompt);
argv = l_parse_args(prompt, &argc);
if (!argv) {
display("Invalid command\n");
goto done;
}
command_process_prompt(argv, argc);
done:
l_free(prompt);

View File

@ -42,7 +42,8 @@ void display_command_line(const char *command_family,
void display_refresh_timeout_set(void);
void display_refresh_reset(void);
void display_refresh_set_cmd(const char *family, const char *entity,
const struct command *cmd, char *args);
const struct command *cmd,
char **argv, int argc);
void display_enable_cmd_prompt(void);
void display_disable_cmd_prompt(void);

View File

@ -244,7 +244,7 @@ static struct proxy_interface_type known_networks_interface_type = {
.ops = &known_networks_ops,
};
static enum cmd_status cmd_list(const char *entity, char *args)
static enum cmd_status cmd_list(const char *entity, char **args, int argc)
{
struct proxy_interface *proxy =
proxy_interface_find(IWD_KNOWN_NETWORKS_INTREFACE,
@ -259,9 +259,8 @@ static enum cmd_status cmd_list(const char *entity, char *args)
return CMD_STATUS_OK;
}
static enum cmd_status cmd_forget(const char *entity, char *args)
static enum cmd_status cmd_forget(const char *entity, char **argv, int argc)
{
struct network_args *network_args;
const struct l_queue_entry *entry;
struct known_network *network = NULL;
struct known_network *net;
@ -274,13 +273,8 @@ static enum cmd_status cmd_forget(const char *entity, char *args)
if (!proxy)
return CMD_STATUS_FAILED;
network_args = network_parse_args(args);
if (!network_args || !network_args->name) {
network_args_destroy(network_args);
if (argc < 1)
return CMD_STATUS_INVALID_ARGS;
}
known_networks = proxy_interface_get_data(proxy);
match = NULL;
@ -289,7 +283,7 @@ static enum cmd_status cmd_forget(const char *entity, char *args)
entry = entry->next) {
net = entry->data;
if (strcmp(net->name, network_args->name))
if (strcmp(net->name, argv[0]))
continue;
if (!match)
@ -299,20 +293,16 @@ static enum cmd_status cmd_forget(const char *entity, char *args)
}
if (!match) {
display("Invalid network name '%s'\n", network_args->name);
network_args_destroy(network_args);
display("Invalid network name '%s'\n", argv[0]);
return CMD_STATUS_INVALID_VALUE;
}
if (l_queue_length(match) > 1) {
if (!network_args->type) {
if (argc < 2) {
display("Provided network name is ambiguous. "
"Please specify security type.\n");
l_queue_destroy(match, NULL);
network_args_destroy(network_args);
return CMD_STATUS_INVALID_VALUE;
}
@ -320,7 +310,7 @@ static enum cmd_status cmd_forget(const char *entity, char *args)
entry = entry->next) {
net = entry->data;
if (!strcmp(net->type, network_args->type)) {
if (!strcmp(net->type, argv[1])) {
network = net;
break;
}
@ -330,11 +320,9 @@ static enum cmd_status cmd_forget(const char *entity, char *args)
}
l_queue_destroy(match, NULL);
network_args_destroy(network_args);
if (!network) {
display("No network with specified parameters was found\n");
return CMD_STATUS_INVALID_VALUE;
}

View File

@ -64,87 +64,6 @@ void network_connect(const struct proxy_interface *proxy)
check_errors_method_callback);
}
static const char *skip_spaces(const char *p)
{
while (*p == ' ')
p++;
return p;
}
struct network_args *network_parse_args(const char *args)
{
struct network_args *network_args;
char **arg_arr;
size_t quoted_len = 0;
size_t i;
const char *p;
if (unlikely(!args))
return NULL;
if (args[0] == '\0')
return NULL;
args = skip_spaces(args);
p = args;
network_args = l_new(struct network_args, 1);
if (*p == '"') {
for (++p, i = 0; *p; p++) {
i++;
if (*p != '"')
continue;
quoted_len = i;
}
if (!quoted_len) {
p = args;
goto split;
}
network_args->name = l_strndup(args + 1, quoted_len - 1);
p = args + quoted_len + 1;
p = skip_spaces(p);
}
split:
arg_arr = l_strsplit(p, ' ');
if (!arg_arr || !arg_arr[0])
goto done;
if (quoted_len) {
network_args->type = l_strdup(arg_arr[0]);
} else {
network_args->name = l_strdup(arg_arr[0]);
i = 1;
while (arg_arr[i] && *arg_arr[i] == '\0')
i++;
network_args->type = l_strdup(arg_arr[i]);
}
done:
l_strfreev(arg_arr);
return network_args;
}
void network_args_destroy(struct network_args *network_args)
{
if (unlikely(!network_args))
return;
l_free(network_args->name);
l_free(network_args->type);
l_free(network_args);
}
static const char *get_name(const void *data)
{
const struct network *network = data;

View File

@ -21,16 +21,13 @@
*/
struct network_args {
char *name;
char *type;
const char *name;
const char *type;
};
bool network_is_connected(const char *path);
void network_connect(const struct proxy_interface *proxy);
struct network_args *network_parse_args(const char *args);
void network_args_destroy(struct network_args *network_args);
char *network_name_completion(const struct proxy_interface *device,
const char *text, int state);

View File

@ -45,25 +45,3 @@ bool properties_builder_append_on_off_variant(
return false;
}
bool properties_parse_args(char *args, char **name, char **value)
{
char **arg_arr;
if (!args)
return false;
arg_arr = l_strsplit(args, ' ');
if (!arg_arr || !arg_arr[0] || !arg_arr[1]) {
l_strfreev(arg_arr);
return false;
}
*name = l_strdup(arg_arr[0]);
*value = l_strdup(arg_arr[1]);
l_strfreev(arg_arr);
return true;
}

View File

@ -34,5 +34,3 @@ static const struct property_value_options properties_on_off_opts[] = {
bool properties_builder_append_on_off_variant(
struct l_dbus_message_builder *builder,
const char *value_str);
bool properties_parse_args(char *args, char **name, char **value);

View File

@ -139,7 +139,7 @@ static void display_wsc_inline(const char *margin, const void *data)
20, proxy_interface_get_identity_str(wsc->device));
}
static enum cmd_status cmd_list(const char *device_name, char *args)
static enum cmd_status cmd_list(const char *device_name, char **argv, int argc)
{
const struct l_queue_entry *entry;
struct l_queue *match =
@ -168,7 +168,8 @@ static enum cmd_status cmd_list(const char *device_name, char *args)
return CMD_STATUS_OK;
}
static enum cmd_status cmd_push_button(const char *device_name, char *args)
static enum cmd_status cmd_push_button(const char *device_name,
char **argv, int argc)
{
const struct proxy_interface *proxy = device_wsc_get(device_name);
@ -184,7 +185,8 @@ static enum cmd_status cmd_push_button(const char *device_name, char *args)
return CMD_STATUS_OK;
}
static enum cmd_status cmd_start_user_pin(const char *device_name, char *args)
static enum cmd_status cmd_start_user_pin(const char *device_name,
char **argv, int argc)
{
const struct proxy_interface *proxy = device_wsc_get(device_name);
@ -194,13 +196,17 @@ static enum cmd_status cmd_start_user_pin(const char *device_name, char *args)
return CMD_STATUS_INVALID_VALUE;
}
if (argc != 1)
return CMD_STATUS_INVALID_ARGS;
proxy_interface_method_call(proxy, "StartPin", "s",
check_errors_method_callback, args);
check_errors_method_callback, argv[0]);
return CMD_STATUS_OK;
}
static enum cmd_status cmd_start_pin(const char *device_name, char *args)
static enum cmd_status cmd_start_pin(const char *device_name,
char **argv, int argc)
{
const struct proxy_interface *proxy = device_wsc_get(device_name);
@ -216,7 +222,8 @@ static enum cmd_status cmd_start_pin(const char *device_name, char *args)
return CMD_STATUS_OK;
}
static enum cmd_status cmd_cancel(const char *device_name, char *args)
static enum cmd_status cmd_cancel(const char *device_name,
char **argv, int argc)
{
const struct proxy_interface *proxy = device_wsc_get(device_name);