Browse Source

hostapd_cli: Start using src/utils/edit*.c

This brings hostapd_cli closer to the design used in wpa_cli
and allows command history and editing mechanisms to be added.
Jouni Malinen 13 years ago
parent
commit
4283805972
2 changed files with 97 additions and 65 deletions
  1. 13 2
      hostapd/Makefile
  2. 84 63
      hostapd/hostapd_cli.c

+ 13 - 2
hostapd/Makefile

@@ -52,6 +52,8 @@ OBJS += ../src/ap/wpa_auth_ie.o
 OBJS += ../src/ap/preauth_auth.o
 OBJS += ../src/ap/pmksa_cache_auth.o
 
+OBJS_c = hostapd_cli.o ../src/common/wpa_ctrl.o ../src/utils/os_$(CONFIG_OS).o
+
 NEED_RC4=y
 NEED_AES=y
 NEED_MD5=y
@@ -74,7 +76,11 @@ LIBS_h += -lbfd
 endif
 endif
 
-OBJS += ../src/utils/eloop.o
+ifndef CONFIG_ELOOP
+CONFIG_ELOOP=eloop
+endif
+OBJS += ../src/utils/$(CONFIG_ELOOP).o
+OBJS_c += ../src/utils/$(CONFIG_ELOOP).o
 OBJS += ../src/utils/common.o
 OBJS += ../src/utils/wpa_debug.o
 OBJS += ../src/utils/wpabuf.o
@@ -736,6 +742,12 @@ CFLAGS += -DCONFIG_P2P_MANAGER
 OBJS += ../src/ap/p2p_hostapd.o
 endif
 
+ifdef CONFIG_WPA_CLI_EDIT
+OBJS_c += ../src/utils/edit.o
+else
+OBJS_c += ../src/utils/edit_simple.o
+endif
+
 ifdef CONFIG_NO_STDOUT_DEBUG
 CFLAGS += -DCONFIG_NO_STDOUT_DEBUG
 endif
@@ -784,7 +796,6 @@ hostapd: $(BCHECK) $(OBJS)
 	$(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS)
 	@$(E) "  LD " $@
 
-OBJS_c = hostapd_cli.o ../src/common/wpa_ctrl.o ../src/utils/os_$(CONFIG_OS).o
 ifdef CONFIG_WPA_TRACE
 OBJS_c += ../src/utils/trace.o
 OBJS_c += ../src/utils/wpa_debug.o

+ 84 - 63
hostapd/hostapd_cli.c

@@ -16,7 +16,9 @@
 #include <dirent.h>
 
 #include "common/wpa_ctrl.h"
-#include "common.h"
+#include "utils/common.h"
+#include "utils/eloop.h"
+#include "utils/edit.h"
 #include "common/version.h"
 
 
@@ -113,6 +115,7 @@ static char *ctrl_ifname = NULL;
 static const char *pid_file = NULL;
 static const char *action_file = NULL;
 static int ping_interval = 5;
+static int interactive = 0;
 
 
 static void usage(void)
@@ -588,6 +591,8 @@ static int hostapd_cli_cmd_license(struct wpa_ctrl *ctrl, int argc,
 static int hostapd_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
 {
 	hostapd_cli_quit = 1;
+	if (interactive)
+		eloop_terminate();
 	return 0;
 }
 
@@ -801,70 +806,39 @@ static void hostapd_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
 }
 
 
-static void hostapd_cli_interactive(void)
-{
-	const int max_args = 10;
-	char cmd[256], *res, *argv[max_args], *pos;
-	int argc;
+#define max_args 10
 
-	printf("\nInteractive mode\n\n");
+static int tokenize_cmd(char *cmd, char *argv[])
+{
+	char *pos;
+	int argc = 0;
 
-	do {
-		hostapd_cli_recv_pending(ctrl_conn, 0, 0);
-		printf("> ");
-		alarm(ping_interval);
-		res = fgets(cmd, sizeof(cmd), stdin);
-		alarm(0);
-		if (res == NULL)
-			break;
-		pos = cmd;
-		while (*pos != '\0') {
-			if (*pos == '\n') {
-				*pos = '\0';
-				break;
-			}
+	pos = cmd;
+	for (;;) {
+		while (*pos == ' ')
 			pos++;
+		if (*pos == '\0')
+			break;
+		argv[argc] = pos;
+		argc++;
+		if (argc == max_args)
+			break;
+		if (*pos == '"') {
+			char *pos2 = os_strrchr(pos, '"');
+			if (pos2)
+				pos = pos2 + 1;
 		}
-		argc = 0;
-		pos = cmd;
-		for (;;) {
-			while (*pos == ' ')
-				pos++;
-			if (*pos == '\0')
-				break;
-			argv[argc] = pos;
-			argc++;
-			if (argc == max_args)
-				break;
-			while (*pos != '\0' && *pos != ' ')
-				pos++;
-			if (*pos == ' ')
-				*pos++ = '\0';
-		}
-		if (argc)
-			wpa_request(ctrl_conn, argc, argv);
-	} while (!hostapd_cli_quit);
-}
-
-
-static void hostapd_cli_cleanup(void)
-{
-	hostapd_cli_close_connection();
-	if (pid_file)
-		os_daemonize_terminate(pid_file);
-
-	os_program_deinit();
-}
-
+		while (*pos != '\0' && *pos != ' ')
+			pos++;
+		if (*pos == ' ')
+			*pos++ = '\0';
+	}
 
-static void hostapd_cli_terminate(int sig)
-{
-	hostapd_cli_cleanup();
-	exit(0);
+	return argc;
 }
 
 
-static void hostapd_cli_alarm(int sig)
+static void hostapd_cli_ping(void *eloop_ctx, void *timeout_ctx)
 {
 	if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
 		printf("Connection to hostapd lost - trying to reconnect\n");
@@ -884,7 +858,55 @@ static void hostapd_cli_alarm(int sig)
 	}
 	if (ctrl_conn)
 		hostapd_cli_recv_pending(ctrl_conn, 1, 0);
-	alarm(ping_interval);
+	eloop_register_timeout(ping_interval, 0, hostapd_cli_ping, NULL, NULL);
+}
+
+
+static void hostapd_cli_eloop_terminate(int sig, void *signal_ctx)
+{
+	eloop_terminate();
+}
+
+
+static void hostapd_cli_edit_cmd_cb(void *ctx, char *cmd)
+{
+	char *argv[max_args];
+	int argc;
+	argc = tokenize_cmd(cmd, argv);
+	if (argc)
+		wpa_request(ctrl_conn, argc, argv);
+}
+
+
+static void hostapd_cli_edit_eof_cb(void *ctx)
+{
+	eloop_terminate();
+}
+
+
+static void hostapd_cli_interactive(void)
+{
+	printf("\nInteractive mode\n\n");
+
+	eloop_register_signal_terminate(hostapd_cli_eloop_terminate, NULL);
+	edit_init(hostapd_cli_edit_cmd_cb, hostapd_cli_edit_eof_cb,
+		  NULL, NULL, NULL);
+	eloop_register_timeout(ping_interval, 0, hostapd_cli_ping, NULL, NULL);
+
+	eloop_run();
+
+	edit_deinit(NULL, NULL);
+	eloop_cancel_timeout(hostapd_cli_ping, NULL, NULL);
+}
+
+
+static void hostapd_cli_cleanup(void)
+{
+	hostapd_cli_close_connection();
+	if (pid_file)
+		os_daemonize_terminate(pid_file);
+
+	os_program_deinit();
 }
 
 
@@ -927,7 +949,6 @@ static void hostapd_cli_action(struct wpa_ctrl *ctrl)
 
 int main(int argc, char *argv[])
 {
-	int interactive;
 	int warning_displayed = 0;
 	int c;
 	int daemonize = 0;
@@ -975,6 +996,9 @@ int main(int argc, char *argv[])
 		       hostapd_cli_license);
 	}
 
+	if (eloop_init())
+		return -1;
+
 	for (;;) {
 		if (ctrl_ifname == NULL) {
 			struct dirent *dent;
@@ -1014,10 +1038,6 @@ int main(int argc, char *argv[])
 		continue;
 	}
 
-	signal(SIGINT, hostapd_cli_terminate);
-	signal(SIGTERM, hostapd_cli_terminate);
-	signal(SIGALRM, hostapd_cli_alarm);
-
 	if (interactive || action_file) {
 		if (wpa_ctrl_attach(ctrl_conn) == 0) {
 			hostapd_cli_attached = 1;
@@ -1039,6 +1059,7 @@ int main(int argc, char *argv[])
 		wpa_request(ctrl_conn, argc - optind, &argv[optind]);
 
 	os_free(ctrl_ifname);
+	eloop_destroy();
 	hostapd_cli_cleanup();
 	return 0;
 }