summaryrefslogtreecommitdiff
path: root/client/input.c
diff options
context:
space:
mode:
authorPatrik Flykt <patrik.flykt@linux.intel.com>2013-03-27 13:53:49 +0200
committerPatrik Flykt <patrik.flykt@linux.intel.com>2013-04-04 10:22:13 +0300
commit3ff40ccff44a46e735189b528abd73a3ff7a0511 (patch)
tree18686c3c705fa7e47271f574967d849f2dd3b091 /client/input.c
parent4f21d25e38219c3b909674327d66c2d6219e99c2 (diff)
downloadconnman-3ff40ccff44a46e735189b528abd73a3ff7a0511.tar.gz
connman-3ff40ccff44a46e735189b528abd73a3ff7a0511.tar.bz2
connman-3ff40ccff44a46e735189b528abd73a3ff7a0511.zip
client: Add input handling
Set up readline command line input handling. Add helper functions to save and redraw the command line when output needs to be printed to the screen.
Diffstat (limited to 'client/input.c')
-rw-r--r--client/input.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/client/input.c b/client/input.c
new file mode 100644
index 00000000..1a313fc7
--- /dev/null
+++ b/client/input.c
@@ -0,0 +1,184 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2012-2013 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <glib.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+
+#include <gdbus.h>
+#include "input.h"
+#include "commands.h"
+
+static DBusConnection *connection;
+static GMainLoop *main_loop;
+static bool interactive = false;
+
+static bool save_input;
+static char *saved_line;
+static int saved_point;
+
+void __connmanctl_quit(void)
+{
+ if (main_loop != NULL)
+ g_main_loop_quit(main_loop);
+}
+
+bool __connmanctl_is_interactive(void)
+{
+ return interactive;
+}
+
+void __connmanctl_save_rl(void)
+{
+ if (interactive == false)
+ return;
+
+ save_input = !RL_ISSTATE(RL_STATE_DONE);
+
+ if (save_input) {
+ saved_point = rl_point;
+ saved_line = rl_copy_text(0, rl_end);
+ rl_save_prompt();
+ rl_replace_line("", 0);
+ rl_redisplay();
+ }
+}
+
+void __connmanctl_redraw_rl(void)
+{
+ if (interactive == false)
+ return;
+
+ if (save_input) {
+ rl_restore_prompt();
+ rl_replace_line(saved_line, 0);
+ rl_point = saved_point;
+ rl_redisplay();
+ free(saved_line);
+ }
+
+ save_input = 0;
+}
+
+static void rl_handler(char *input)
+{
+ char **args;
+ int num, err;
+
+ if (input == NULL) {
+ 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 = commands(connection, args, num);
+
+ g_strfreev(args);
+
+ if (err > 0)
+ g_main_loop_quit(main_loop);
+}
+
+static gboolean input_handler(GIOChannel *channel, GIOCondition condition,
+ gpointer user_data)
+{
+ if (condition & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
+ g_main_loop_quit(main_loop);
+ return FALSE;
+ }
+
+ rl_callback_read_char();
+ return TRUE;
+}
+
+int __connmanctl_input_init(int argc, char *argv[])
+{
+ guint source = 0;
+ int err;
+ DBusError dbus_err;
+
+ dbus_error_init(&dbus_err);
+ connection = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, &dbus_err);
+
+ if (dbus_error_is_set(&dbus_err)) {
+ fprintf(stderr, "Error: %s\n", dbus_err.message);
+ dbus_error_free(&dbus_err);
+ return 1;
+ }
+
+ if (argc < 2) {
+ GIOChannel *channel;
+
+ interactive = true;
+
+ channel = g_io_channel_unix_new(fileno(stdin));
+ source = g_io_add_watch(channel,
+ G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
+ input_handler, NULL);
+ g_io_channel_unref(channel);
+
+ rl_callback_handler_install("connmanctl> ", rl_handler);
+ err = -EINPROGRESS;
+
+ } else {
+ interactive = false;
+ err = commands(connection, argv + 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) {
+ rl_callback_handler_remove();
+ rl_message("");
+ }
+
+ dbus_connection_unref(connection);
+ if (main_loop != NULL)
+ g_main_loop_unref(main_loop);
+
+ if (err < 0)
+ err = -err;
+ else
+ err = 0;
+
+ return err;
+}