Code

frontend/connection: Reset state after handling a command.
[sysdb.git] / src / frontend / connection.c
1 /*
2  * SysDB - src/frontend/connection.c
3  * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
28 #include "sysdb.h"
29 #include "frontend/connection.h"
30 #include "utils/strbuf.h"
32 #include <assert.h>
33 #include <errno.h>
35 #include <arpa/inet.h>
37 #include <string.h>
39 /*
40  * connection handler functions
41  */
43 static uint32_t
44 connection_get_int32(sdb_conn_t *conn, size_t offset)
45 {
46         const char *data;
47         uint32_t n;
49         assert(conn && (sdb_strbuf_len(conn->buf) >= offset + sizeof(uint32_t)));
51         data = sdb_strbuf_string(conn->buf);
52         memcpy(&n, data + offset, sizeof(n));
53         n = ntohl(n);
54         return n;
55 } /* connection_get_int32 */
57 static int
58 command_handle(sdb_conn_t *conn)
59 {
60         assert(conn && conn->cmd && conn->cmd_len);
61         /* XXX */
62         sdb_strbuf_skip(conn->buf, conn->cmd_len);
63         conn->cmd = conn->cmd_len = 0;
64         return 0;
65 } /* command_handle */
67 /* initialize the connection state information */
68 static int
69 command_init(sdb_conn_t *conn)
70 {
71         assert(conn && (! conn->cmd) && (! conn->cmd_len));
73         conn->cmd = connection_get_int32(conn, 0);
74         conn->cmd_len = connection_get_int32(conn, sizeof(uint32_t));
75         sdb_strbuf_skip(conn->buf, 2 * sizeof(uint32_t));
76         return 0;
77 } /* command_init */
79 /* returns negative value on error, 0 on EOF, number of octets else */
80 static ssize_t
81 connection_read(sdb_conn_t *conn)
82 {
83         ssize_t n = 0;
85         while (42) {
86                 ssize_t status;
88                 errno = 0;
89                 status = sdb_strbuf_read(conn->buf, conn->fd, 1024);
90                 if (status < 0) {
91                         if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
92                                 break;
93                         return (int)status;
94                 }
95                 else if (! status) /* EOF */
96                         break;
98                 n += status;
99         }
101         return n;
102 } /* connection_read */
104 /*
105  * public API
106  */
108 ssize_t
109 sdb_connection_read(sdb_conn_t *conn)
111         ssize_t n = 0;
113         while (42) {
114                 ssize_t status = connection_read(conn);
116                 if ((! conn->cmd) && (! conn->cmd_len)
117                                 && (sdb_strbuf_len(conn->buf) >= 2 * sizeof(int32_t)))
118                         command_init(conn);
119                 if (conn->cmd_len && (sdb_strbuf_len(conn->buf) >= conn->cmd_len))
120                         command_handle(conn);
122                 if (status <= 0)
123                         break;
125                 n += status;
126         }
127         return n;
128 } /* sdb_connection_read */
130 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */