Code

plugin: Make sdb_plugin_info_t public.
[sysdb.git] / src / client / sock.c
index a2417ad6d872029e8c80f51d83899b65e9026a06..b60bad45e2cf97d47d2c101513c030f4a27fff5e 100644 (file)
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if HAVE_CONFIG_H
+#      include "config.h"
+#endif /* HAVE_CONFIG_H */
+
 #include "client/sock.h"
 #include "utils/error.h"
 #include "utils/strbuf.h"
@@ -52,6 +56,7 @@
 struct sdb_client {
        char *address;
        int   fd;
+       _Bool eof;
 };
 
 /*
@@ -104,6 +109,7 @@ sdb_client_create(const char *address)
        }
        memset(client, 0, sizeof(*client));
        client->fd = -1;
+       client->eof = 1;
 
        client->address = strdup(address);
        if (! client->address) {
@@ -154,6 +160,7 @@ sdb_client_connect(sdb_client_t *client, const char *username)
 
        if (client->fd < 0)
                return -1;
+       client->eof = 0;
 
        /* XXX */
        if (! username)
@@ -172,24 +179,54 @@ sdb_client_connect(sdb_client_t *client, const char *username)
        buf = sdb_strbuf_create(64);
        rstatus = 0;
        status = sdb_client_recv(client, &rstatus, buf);
+       if ((status > 0) && (rstatus == CONNECTION_OK)) {
+               sdb_strbuf_destroy(buf);
+               return 0;
+       }
+
        if (status < 0) {
                char errbuf[1024];
-               sdb_client_close(client);
-               sdb_strbuf_destroy(buf);
                sdb_log(SDB_LOG_ERR, "Failed to receive server response: %s",
                                sdb_strerror(errno, errbuf, sizeof(errbuf)));
-               return (int)status;
        }
+       else if (client->eof)
+               sdb_log(SDB_LOG_ERR, "Encountered end-of-file while waiting "
+                               "for server response");
 
        if (rstatus != CONNECTION_OK) {
-               sdb_client_close(client);
-               sdb_strbuf_destroy(buf);
                sdb_log(SDB_LOG_ERR, "Access denied for user '%s'", username);
-               return -((int)rstatus);
+               status = -((int)rstatus);
        }
-       return 0;
+
+       sdb_client_close(client);
+       sdb_strbuf_destroy(buf);
+       return (int)status;
 } /* sdb_client_connect */
 
+int
+sdb_client_sockfd(sdb_client_t *client)
+{
+       if (! client)
+               return -1;
+       return client->fd;
+} /* sdb_client_sockfd */
+
+int
+sdb_client_shutdown(sdb_client_t *client, int how)
+{
+       if (! client) {
+               errno = ENOTSOCK;
+               return -1;
+       }
+
+       if (client->fd < 0) {
+               errno = EBADF;
+               return -1;
+       }
+
+       return shutdown(client->fd, how);
+} /* sdb_client_shutdown */
+
 void
 sdb_client_close(sdb_client_t *client)
 {
@@ -198,6 +235,7 @@ sdb_client_close(sdb_client_t *client)
 
        close(client->fd);
        client->fd = -1;
+       client->eof = 1;
 } /* sdb_client_close */
 
 ssize_t
@@ -222,14 +260,14 @@ sdb_client_recv(sdb_client_t *client,
 
        size_t data_offset = sdb_strbuf_len(buf);
 
+       if (code)
+               *code = UINT32_MAX;
+
        if ((! client) || (! client->fd) || (! buf)) {
                errno = EBADF;
                return -1;
        }
 
-       if (code)
-               *code = UINT32_MAX;
-
        while (42) {
                ssize_t status;
 
@@ -243,8 +281,10 @@ sdb_client_recv(sdb_client_t *client,
                                continue;
                        return status;
                }
-               else if (! status) /* EOF */
+               else if (! status) {
+                       client->eof = 1;
                        break;
+               }
 
                total += (size_t)status;
 
@@ -282,5 +322,13 @@ sdb_client_recv(sdb_client_t *client,
        return (ssize_t)total;
 } /* sdb_client_recv */
 
+_Bool
+sdb_client_eof(sdb_client_t *client)
+{
+       if ((! client) || (client->fd < 0))
+               return 1;
+       return client->eof;
+} /* sdb_client_eof */
+
 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */