diff --git a/hostapd/Makefile b/hostapd/Makefile index d05975b29..3ed025dc3 100644 --- a/hostapd/Makefile +++ b/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 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c index a48d77325..007126103 100644 --- a/hostapd/hostapd_cli.c +++ b/hostapd/hostapd_cli.c @@ -16,7 +16,9 @@ #include #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) +#define max_args 10 + +static int tokenize_cmd(char *cmd, char *argv[]) { - const int max_args = 10; - char cmd[256], *res, *argv[max_args], *pos; - int argc; + char *pos; + int argc = 0; - printf("\nInteractive mode\n\n"); - - 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); + while (*pos != '\0' && *pos != ' ') + pos++; + if (*pos == ' ') + *pos++ = '\0'; + } + + return argc; } -static void hostapd_cli_cleanup(void) -{ - hostapd_cli_close_connection(); - if (pid_file) - os_daemonize_terminate(pid_file); - - os_program_deinit(); -} - - -static void hostapd_cli_terminate(int sig) -{ - hostapd_cli_cleanup(); - exit(0); -} - - -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; }