028f3776966b233ec2371b52653f10ce1752c5c0
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 return 0;
64 } /* command_handle */
66 /* initialize the connection state information */
67 static int
68 command_init(sdb_conn_t *conn)
69 {
70 assert(conn && (! conn->cmd) && (! conn->cmd_len));
72 conn->cmd = connection_get_int32(conn, 0);
73 conn->cmd_len = connection_get_int32(conn, sizeof(uint32_t));
74 sdb_strbuf_skip(conn->buf, 2 * sizeof(uint32_t));
75 return 0;
76 } /* command_init */
78 /* returns negative value on error, 0 on EOF, number of octets else */
79 static ssize_t
80 connection_read(sdb_conn_t *conn)
81 {
82 ssize_t n = 0;
84 while (42) {
85 ssize_t status;
87 errno = 0;
88 status = sdb_strbuf_read(conn->buf, conn->fd, 1024);
89 if (status < 0) {
90 if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
91 break;
92 return (int)status;
93 }
94 else if (! status) /* EOF */
95 break;
97 n += status;
98 }
100 return n;
101 } /* connection_read */
103 /*
104 * public API
105 */
107 ssize_t
108 sdb_connection_read(sdb_conn_t *conn)
109 {
110 ssize_t n = 0;
112 while (42) {
113 ssize_t status = connection_read(conn);
114 if (status <= 0)
115 break;
117 n += status;
119 if (conn->cmd_len && (sdb_strbuf_len(conn->buf) >= conn->cmd_len))
120 command_handle(conn);
121 else if (sdb_strbuf_len(conn->buf) >= 2 * sizeof(int32_t))
122 command_init(conn);
123 }
124 return n;
125 } /* sdb_connection_read */
127 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */