index 3814f0c2def7a239d8397d9cad4558cbd52112ae..f0f86ea2a9bff1e264013bf39c3ab31758919c63 100644 (file)
--- a/src/tools/sysdb/input.c
+++ b/src/tools/sysdb/input.c
#include "utils/error.h"
#include "utils/strbuf.h"
+#include <errno.h>
+
#include <sys/select.h>
#include <stdio.h>
*/
static struct termios orig_term_attrs;
+static bool have_orig_term_attrs;
/*
* private helper functions
{
struct termios attrs;
+ if (! have_orig_term_attrs) {
+ memset(&orig_term_attrs, 0, sizeof(orig_term_attrs));
+ tcgetattr(STDIN_FILENO, &orig_term_attrs);
+ atexit(reset_term_attrs);
+ have_orig_term_attrs = 1;
+ }
+
/* setup terminal to operate in non-canonical mode
* and single character input */
- memset(&orig_term_attrs, 0, sizeof(orig_term_attrs));
- tcgetattr(STDIN_FILENO, &orig_term_attrs);
- atexit(reset_term_attrs);
-
memset(&attrs, 0, sizeof(attrs));
tcgetattr(STDIN_FILENO, &attrs);
attrs.c_lflag &= (tcflag_t)(~ICANON);
return;
}
- sdb_strbuf_append(sysdb_input->input, line);
- sdb_strbuf_append(sysdb_input->input, "\n");
+ sdb_strbuf_append(sysdb_input->input, "%s\n", line);
free(line);
- rl_callback_handler_remove();
+ if (sysdb_input->interactive)
+ rl_callback_handler_remove();
} /* handle_input */
/* wait for a new line of data to be available */
const char *prompt = "sysdb=> ";
- if (sysdb_input->query_len)
- prompt = "sysdb-> ";
+ len = sdb_strbuf_len(sysdb_input->input);
+
+ if (! sysdb_input->interactive) {
+ char *line = readline("");
+ handle_input(line);
+ return (ssize_t)(sdb_strbuf_len(sysdb_input->input) - len);
+ }
+
+ if (sysdb_input->have_input)
+ prompt = " -> ";
+ if (sdb_client_eof(sysdb_input->client))
+ prompt = "!-> ";
rl_callback_handler_install(prompt, handle_input);
client_fd = sdb_client_sockfd(sysdb_input->client);
-
- len = sdb_strbuf_len(sysdb_input->input);
while ((sdb_strbuf_len(sysdb_input->input) == len)
&& (! sysdb_input->eof)) {
- int n;
+ bool connected = !sdb_client_eof(sysdb_input->client);
+ int max_fd, n;
/* XXX: some versions of libedit don't properly reset the terminal in
* rl_callback_read_char(); detect those versions */
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
- FD_SET(client_fd, &fds);
+ max_fd = STDIN_FILENO;
- n = select(client_fd + 1, &fds, NULL, NULL, /* timeout = */ NULL);
+ if (connected) {
+ FD_SET(client_fd, &fds);
+ if (client_fd > max_fd)
+ max_fd = client_fd;
+ }
+
+ n = select(max_fd + 1, &fds, NULL, NULL, /* timeout = */ NULL);
if (n < 0)
return (ssize_t)n;
else if (! n)
continue;
}
- if (! FD_ISSET(client_fd, &fds))
+ if ((! connected) || (! FD_ISSET(client_fd, &fds)))
continue;
+ /* some response / error message from the server pending */
+ /* XXX: clear current line */
+ printf("\n");
+ sdb_command_print_reply(sysdb_input->client);
+
if (sdb_client_eof(sysdb_input->client)) {
- /* XXX: try to reconnect */
- printf("\n");
+ rl_callback_handler_remove();
+ /* XXX */
sdb_log(SDB_LOG_ERR, "Remote side closed the connection.");
- /* return EOF */
+ /* return EOF -> restart scanner */
return 0;
}
-
- /* some response / error message from the server pending */
- /* XXX: clear current line */
- printf("\n");
- sdb_command_print_reply(sysdb_input);
- rl_forced_update_display();
+ else
+ rl_forced_update_display();
}
/* new data available */
/* register input handler */
sysdb_input = input;
- if (! isatty(STDIN_FILENO))
- return -1;
-
- term_rawmode();
+ input->interactive = isatty(STDIN_FILENO) != 0;
+ errno = 0;
+ if (input->interactive)
+ term_rawmode();
return 0;
} /* sdb_input_init */
+void
+sdb_input_reset(sdb_input_t *input)
+{
+ sdb_input_t reset = SDB_INPUT_INIT;
+
+ if (! input)
+ return;
+
+ if (input->client)
+ sdb_client_destroy(input->client);
+ if (input->user)
+ free(input->user);
+ if (input->input)
+ sdb_strbuf_destroy(input->input);
+
+ *input = reset;
+} /* sdb_input_reset */
+
int
sdb_input_mainloop(void)
{
- yylex();
+ while (! sysdb_input->eof)
+ yylex();
return 0;
} /* sdb_input_mainloop */
ssize_t
-sdb_input_readline(char *buf, int *n_chars, size_t max_chars)
+sdb_input_readline(char *buf, size_t *n_chars, size_t max_chars)
{
const char *data;
size_t len;
int
sdb_input_exec_query(void)
{
- char *query = sdb_command_exec(sysdb_input);
+ char *query = NULL;
+
+ HIST_ENTRY *hist;
+ const char *prev = NULL;
- HIST_ENTRY *current_hist;
- const char *hist_line = NULL;
+ if (! sysdb_input->have_input) {
+ /* empty line */
+ if (sdb_client_eof(sysdb_input->client))
+ sdb_input_reconnect();
+ return 0;
+ }
+ query = sdb_command_exec(sysdb_input);
if (! query)
return -1;
- current_hist = current_history();
- if (current_hist)
- hist_line = current_hist->line;
+ hist = history_get(history_length);
+ if (hist)
+ prev = hist->line;
if (*query != ' ')
- if ((! hist_line) || strcmp(hist_line, query))
+ if ((! prev) || strcmp(prev, query))
add_history(query);
free(query);
return 0;
} /* sdb_input_exec_query */
+int
+sdb_input_reconnect(void)
+{
+ sdb_client_close(sysdb_input->client);
+ if (sdb_client_connect(sysdb_input->client, sysdb_input->user)) {
+ sdb_log(SDB_LOG_ERR, "Failed to reconnect to SysDBd");
+ return -1;
+ }
+ sdb_log(SDB_LOG_INFO, "Successfully reconnected to SysDBd");
+ sdb_command_print_server_version(sysdb_input);
+ return 0;
+} /* sdb_input_reconnect */
+
/* vim: set tw=78 sw=4 ts=4 noexpandtab : */