[connman] Added Tizen Wi-Fi Mesh
[platform/upstream/connman.git] / client / input.c
old mode 100644 (file)
new mode 100755 (executable)
index f1aa0d3..d9d2b7b
@@ -2,7 +2,7 @@
  *
  *  Connection Manager
  *
- *  Copyright (C) 2012-2013  Intel Corporation. All rights reserved.
+ *  Copyright (C) 2012-2014  Intel Corporation. All rights reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -45,7 +45,7 @@ static int saved_point;
 
 void __connmanctl_quit(void)
 {
-       if (main_loop != NULL)
+       if (main_loop)
                g_main_loop_quit(main_loop);
 }
 
@@ -56,9 +56,6 @@ bool __connmanctl_is_interactive(void)
 
 void __connmanctl_save_rl(void)
 {
-       if (interactive == false)
-               return;
-
        save_input = !RL_ISSTATE(RL_STATE_DONE);
 
        if (save_input) {
@@ -72,9 +69,6 @@ void __connmanctl_save_rl(void)
 
 void __connmanctl_redraw_rl(void)
 {
-       if (interactive == false)
-               return;
-
        if (save_input) {
                rl_restore_prompt();
                rl_replace_line(saved_line, 0);
@@ -88,26 +82,40 @@ void __connmanctl_redraw_rl(void)
 
 static void rl_handler(char *input)
 {
-       char **args;
-       int num, err;
+       char **args, **trim_args;
+       int num, len, err, i;
 
-       if (input == NULL) {
+       if (!input) {
                rl_newline(1, '\n');
                g_main_loop_quit(main_loop);
                return;
        }
-       if (*input != '\0')
-               add_history(input);
 
        args = g_strsplit(input, " ", 0);
        num = g_strv_length(args);
 
-       err = __connmanctl_commands(connection, args, num);
+       trim_args = g_new0(char *, num + 1);
+       for (i = 0, len = 0; i < num; i++) {
+               if (*args[i] != '\0') {
+                       trim_args[len] = args[i];
+                       len++;
+               }
+       }
 
-       g_strfreev(args);
+       if (len > 0) {
+               HIST_ENTRY *previous = history_get(where_history());
+               if(!previous || strcmp(previous->line, input))
+                       add_history(input);
 
-       if (err > 0)
-               g_main_loop_quit(main_loop);
+               err = __connmanctl_commands(connection, trim_args, len);
+
+               if (err > 0)
+                       g_main_loop_quit(main_loop);
+       }
+
+       g_strfreev(args);
+       g_free(trim_args);
+       free(input);
 }
 
 static gboolean input_handler(GIOChannel *channel, GIOCondition condition,
@@ -122,6 +130,92 @@ static gboolean input_handler(GIOChannel *channel, GIOCondition condition,
        return TRUE;
 }
 
+static char **complete_agent(const char *text, int start, int end)
+{
+       rl_attempted_completion_over = 1;
+
+       return NULL;
+}
+
+/* Return how many parameters we have typed */
+int __connmanctl_input_calc_level(void)
+{
+       int count = 0;
+       char *ptr;
+
+       ptr = rl_line_buffer;
+
+       while (*ptr) {
+               if (*ptr == ' ') {
+                       if (*(ptr + 1) == ' ') {
+                               ptr++;
+                               continue;
+                       } else
+                               count++;
+               }
+               ptr++;
+       }
+
+       return count;
+}
+
+void __connmanctl_input_lookup_end(void)
+{
+       rl_attempted_completion_over = 1;
+}
+
+static char **complete_command(const char *text, int start, int end)
+{
+       if (start == 0) {
+               return rl_completion_matches(text,
+                               __connmanctl_lookup_command);
+
+       } else {
+               __connmanctl_lookup_cb cb;
+               char **str = NULL;
+
+               cb = __connmanctl_get_lookup_func(rl_line_buffer);
+               if (cb)
+                       str = rl_completion_matches(text, cb);
+               else
+                       rl_attempted_completion_over = 1;
+
+               return str;
+       }
+}
+
+static struct {
+       connmanctl_input_func_t cb;
+       void *user_data;
+} agent_handler;
+
+static void rl_agent_handler(char *input)
+{
+       agent_handler.cb(input, agent_handler.user_data);
+}
+
+void __connmanctl_agent_mode(const char *prompt,
+               connmanctl_input_func_t input_handler, void *user_data)
+{
+       agent_handler.cb = input_handler;
+       agent_handler.user_data = user_data;
+
+       if (input_handler)
+               rl_callback_handler_install(prompt, rl_agent_handler);
+       else {
+               rl_set_prompt(prompt);
+               rl_callback_handler_remove();
+               rl_redisplay();
+       }
+       rl_attempted_completion_function = complete_agent;
+}
+
+void __connmanctl_command_mode(void)
+{
+       rl_callback_handler_install("connmanctl> ", rl_handler);
+       rl_attempted_completion_function = complete_command;
+}
+
 int __connmanctl_input_init(int argc, char *argv[])
 {
        char *help[] = {
@@ -131,6 +225,7 @@ int __connmanctl_input_init(int argc, char *argv[])
        guint source = 0;
        int err;
        DBusError dbus_err;
+       GIOChannel *channel;
 
        dbus_error_init(&dbus_err);
        connection = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, &dbus_err);
@@ -142,8 +237,6 @@ int __connmanctl_input_init(int argc, char *argv[])
        }
 
        if (argc < 2) {
-               GIOChannel *channel;
-
                interactive = true;
 
                channel = g_io_channel_unix_new(fileno(stdin));
@@ -152,9 +245,11 @@ int __connmanctl_input_init(int argc, char *argv[])
                                input_handler, NULL);
                g_io_channel_unref(channel);
 
-               rl_callback_handler_install("connmanctl> ", rl_handler);
-               err = -EINPROGRESS;
+               __connmanctl_monitor_completions(connection);
+
+               __connmanctl_command_mode();
 
+               err = -EINPROGRESS;
        } else {
                interactive = false;
 
@@ -163,26 +258,28 @@ int __connmanctl_input_init(int argc, char *argv[])
                        err = __connmanctl_commands(connection, help, 1);
                else
                        err = __connmanctl_commands(connection, argv + 1,
-                                       argc -1);
+                                       argc - 1);
        }
 
        if (err == -EINPROGRESS) {
                main_loop = g_main_loop_new(NULL, FALSE);
                g_main_loop_run(main_loop);
 
-               if (source > 0)
-                       g_source_remove(source);
-
                err = 0;
        }
 
-       if (interactive == true) {
+       if (interactive) {
+               g_source_remove(source);
+               __connmanctl_monitor_completions(NULL);
+
                rl_callback_handler_remove();
+#if !defined TIZEN_EXT
                rl_message("");
+#endif
        }
 
        dbus_connection_unref(connection);
-       if (main_loop != NULL)
+       if (main_loop)
                g_main_loop_unref(main_loop);
 
        if (err < 0)