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)
110 {
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 : */