Code

sysdb: Don't exit if the server closed the connection.
authorSebastian Harl <sh@tokkee.org>
Thu, 11 Dec 2014 08:47:56 +0000 (09:47 +0100)
committerSebastian Harl <sh@tokkee.org>
Thu, 11 Dec 2014 08:47:56 +0000 (09:47 +0100)
Instead, notify the user an try to reconnect before executing the next
command.

src/tools/sysdb/command.c
src/tools/sysdb/input.c
src/tools/sysdb/input.h
src/tools/sysdb/main.c

index 7737a2e15e35e6c9084227669f6f40471ea463e3..f9195a644057ee9b2c849f4f764f4ef6bacd65d4 100644 (file)
@@ -91,6 +91,14 @@ static struct {
        { SDB_CONNECTION_DATA, data_printer },
 };
 
+static void
+clear_query(sdb_input_t *input)
+{
+       sdb_strbuf_skip(input->input, 0, input->query_len);
+       input->tokenizer_pos -= input->query_len;
+       input->query_len = 0;
+} /* clear_query */
+
 /*
  * public API
  */
@@ -165,6 +173,16 @@ sdb_command_exec(sdb_input_t *input)
        while (query_len && (query[query_len - 1]) == '\n')
                --query_len;
 
+       if (sdb_client_eof(input->client)) {
+               sdb_client_close(input->client);
+               if (sdb_client_connect(input->client, input->user)) {
+                       printf("Failed to reconnect to SysDBd.\n");
+                       clear_query(input);
+                       return NULL;
+               }
+               printf("Successfully reconnected to SysDBd.\n");
+       }
+
        if (query_len) {
                data = strndup(query, query_len);
                /* ignore errors; we'll only hide the command from the caller */
@@ -184,9 +202,7 @@ sdb_command_exec(sdb_input_t *input)
                }
        }
 
-       sdb_strbuf_skip(input->input, 0, input->query_len);
-       input->tokenizer_pos -= input->query_len;
-       input->query_len = 0;
+       clear_query(input);
        return data;
 } /* sdb_command_exec */
 
index 9ed11eddd0e26309fab0bbda7333495ae86bd37c..52036028d2905d35555705ec026e2bc30f96c55e 100644 (file)
@@ -161,12 +161,15 @@ input_readline(void)
 
        if (sysdb_input->query_len)
                prompt = "sysdb-> ";
+       if (sdb_client_eof(sysdb_input->client))
+               prompt = "!-> ";
 
        rl_callback_handler_install(prompt, handle_input);
        client_fd = sdb_client_sockfd(sysdb_input->client);
        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 */
@@ -174,9 +177,15 @@ input_readline(void)
 
                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)
@@ -188,22 +197,23 @@ input_readline(void)
                        continue;
                }
 
-               if (! FD_ISSET(client_fd, &fds))
+               if ((! connected) || (! FD_ISSET(client_fd, &fds)))
                        continue;
 
-               if (sdb_client_eof(sysdb_input->client)) {
-                       /* XXX: try to reconnect */
-                       printf("\n");
-                       sdb_log(SDB_LOG_ERR, "Remote side closed the connection.");
-                       /* return EOF */
-                       return 0;
-               }
-
                /* some response / error message from the server pending */
                /* XXX: clear current line */
                printf("\n");
                sdb_command_print_reply(sysdb_input->client);
-               rl_forced_update_display();
+
+               if (sdb_client_eof(sysdb_input->client)) {
+                       rl_callback_handler_remove();
+                       /* XXX */
+                       printf("Remote side closed the connection.\n");
+                       /* return EOF -> restart scanner */
+                       return 0;
+               }
+               else
+                       rl_forced_update_display();
        }
 
        /* new data available */
@@ -230,7 +240,8 @@ sdb_input_init(sdb_input_t *input)
 int
 sdb_input_mainloop(void)
 {
-       yylex();
+       while (! sysdb_input->eof)
+               yylex();
        return 0;
 } /* sdb_input_mainloop */
 
index 0ba5c0a4dd385169fc439c1fe133b33464f609a8..eb13043b4cea2acb948cc3ec031f075311cbb818 100644 (file)
@@ -33,6 +33,7 @@
 
 typedef struct {
        sdb_client_t *client;
+       const char *user;
 
        sdb_strbuf_t *input;
        size_t tokenizer_pos;
@@ -42,7 +43,7 @@ typedef struct {
        bool eof;
 } sdb_input_t;
 
-#define SDB_INPUT_INIT { NULL, NULL, 0, 0, 1, 0 }
+#define SDB_INPUT_INIT { NULL, NULL, NULL, 0, 0, 1, 0 }
 
 /*
  * sysdb_input:
index 6e75ef9b6c7687484848739fda8eeeaf3c85a233..6e10e8d9fd87d937a3d668566f9f4fccf7bbcd7d 100644 (file)
@@ -227,7 +227,6 @@ int
 main(int argc, char **argv)
 {
        const char *host = NULL;
-       const char *user = NULL;
 
        const char *homedir;
        char hist_file[1024] = "";
@@ -246,7 +245,7 @@ main(int argc, char **argv)
                                host = optarg;
                                break;
                        case 'U':
-                               user = optarg;
+                               input.user = optarg;
                                break;
 
                        case 'c':
@@ -289,9 +288,9 @@ main(int argc, char **argv)
 
        if (! host)
                host = DEFAULT_SOCKET;
-       if (! user) {
-               user = get_current_user();
-               if (! user)
+       if (! input.user) {
+               input.user = get_current_user();
+               if (! input.user)
                        exit(1);
        }
 
@@ -300,7 +299,7 @@ main(int argc, char **argv)
                sdb_log(SDB_LOG_ERR, "Failed to create client object");
                exit(1);
        }
-       if (sdb_client_connect(input.client, user)) {
+       if (sdb_client_connect(input.client, input.user)) {
                sdb_log(SDB_LOG_ERR, "Failed to connect to SysDBd");
                sdb_client_destroy(input.client);
                exit(1);
@@ -321,7 +320,7 @@ main(int argc, char **argv)
 
        using_history();
 
-       if ((homedir = get_homedir(user))) {
+       if ((homedir = get_homedir(input.user))) {
                snprintf(hist_file, sizeof(hist_file) - 1,
                                "%s/.sysdb_history", homedir);
                hist_file[sizeof(hist_file) - 1] = '\0';