Annotation of libaitrpc/src/blobcli.c, revision 1.3
1.2 misho 1: /*************************************************************************
2: * (C) 2015 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
3: * by Michael Pounov <misho@openbsd-bg.org>
4: *
5: * $Author: misho $
1.3 ! misho 6: * $Id: blobcli.c,v 1.2.8.1 2024/03/20 16:57:43 misho Exp $
1.2 misho 7: *
8: **************************************************************************
9: The ELWIX and AITNET software is distributed under the following
10: terms:
11:
12: All of the documentation and software included in the ELWIX and AITNET
13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
14:
1.3 ! misho 15: Copyright 2004 - 2024
1.2 misho 16: by Michael Pounov <misho@elwix.org>. All rights reserved.
17:
18: Redistribution and use in source and binary forms, with or without
19: modification, are permitted provided that the following conditions
20: are met:
21: 1. Redistributions of source code must retain the above copyright
22: notice, this list of conditions and the following disclaimer.
23: 2. Redistributions in binary form must reproduce the above copyright
24: notice, this list of conditions and the following disclaimer in the
25: documentation and/or other materials provided with the distribution.
26: 3. All advertising materials mentioning features or use of this software
27: must display the following acknowledgement:
28: This product includes software developed by Michael Pounov <misho@elwix.org>
29: ELWIX - Embedded LightWeight unIX and its contributors.
30: 4. Neither the name of AITNET nor the names of its contributors
31: may be used to endorse or promote products derived from this software
32: without specific prior written permission.
33:
34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44: SUCH DAMAGE.
45: */
46: #include "global.h"
47:
48:
49: /*
50: * rpc_cli_sendBLOB() - Send BLOB to server
51: *
52: * @cli = Client instance
53: * @var = BLOB variable
54: * @data = BLOB data
55: * @tout = BLOB live on server timeout in seconds, if =0 default timeout
56: * return: -1 error, 0 ok, 1 remote error
57: */
58: int
59: rpc_cli_sendBLOB(rpc_cli_t * __restrict cli, ait_val_t * __restrict var,
60: void * __restrict data, int tout)
61: {
62: int ret, len;
63: uint8_t *pos;
64: struct tagBLOBHdr hdr;
65: struct pollfd pfd;
66:
67: if (!cli || !var || !data) {
68: rpc_SetErr(EINVAL, "Invalid arguments");
69: return -1;
70: } else
71: memset(&hdr, 0, sizeof hdr);
72:
73: rpc_addPktSession(&hdr.hdr_session, cli->cli_parent);
74: hdr.hdr_cmd = set;
75: hdr.hdr_var = 0;
76: hdr.hdr_ret = tout;
77: hdr.hdr_len = htonl(AIT_LEN(var));
78:
79: /* send SET request */
80: pfd.fd = cli->cli_sock;
81: pfd.events = POLLOUT;
1.3 ! misho 82: if (poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000) == -1 ||
1.2 misho 83: pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
84: LOGERR;
85: return -1;
86: }
87: if (send(cli->cli_sock, &hdr, sizeof hdr, MSG_NOSIGNAL) == -1) {
88: LOGERR;
89: return -1;
90: }
91:
92: /* send BLOB to server */
93: for (ret = AIT_LEN(var), pos = data; ret > 0; ret -= len, pos += len)
94: if ((len = send(cli->cli_sock, pos, ret, MSG_NOSIGNAL)) == -1) {
95: LOGERR;
96: return -1;
97: }
98:
99: /* wait for reply */
100: pfd.events = POLLIN | POLLPRI;
101: if ((ret = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) < 1 ||
102: pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
103: if (ret)
104: LOGERR;
105: else
106: rpc_SetErr(ETIMEDOUT, "Timeout reached! Server not respond");
107: return -1;
108: }
109: if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
110: LOGERR;
111: return 1;
112: }
113:
114: if (hdr.hdr_cmd != error) {
115: AIT_SET_BLOB(var, ntohl(hdr.hdr_var), ntohl(hdr.hdr_len));
116:
117: if (ntohl(hdr.hdr_len) != AIT_LEN(var)) {
118: rpc_cli_delBLOB(cli, var);
119: AIT_NEW_BLOB(var, ntohl(hdr.hdr_len));
120:
121: rpc_SetErr(ECANCELED, "Bad return length packet");
122: return 1;
123: }
124: }
125:
126: return hdr.hdr_cmd == error;
127: }
128:
129: /*
130: * rpc_cli_recvBLOB() - Receive BLOB from server
131: *
132: * @cli = Client instance
133: * @var = BLOB variable
134: * @data = BLOB data, must be e_free after use!
135: * return: -1 error, 0 ok, 1 remote error
136: */
137: int
138: rpc_cli_recvBLOB(rpc_cli_t * __restrict cli, ait_val_t * __restrict var, void ** __restrict data)
139: {
140: int ret, len;
141: uint8_t *pos;
142: struct pollfd pfd;
143: struct tagBLOBHdr hdr;
144:
145: if (!cli || !var || !data) {
146: rpc_SetErr(EINVAL, "Invalid arguments");
147: return -1;
148: }
149:
150: *data = e_malloc(AIT_LEN(var));
151: if (!*data) {
152: LOGERR;
153: return -1;
154: } else {
155: memset(&hdr, 0, sizeof hdr);
156: memset(*data, 0, AIT_LEN(var));
157: }
158:
159: rpc_addPktSession(&hdr.hdr_session, cli->cli_parent);
160: hdr.hdr_cmd = get;
161: hdr.hdr_var = htonl((uint32_t) AIT_GET_BLOB(var));
162: hdr.hdr_ret = 0;
163: hdr.hdr_len = 0;
164:
165: /* send GET request */
166: pfd.fd = cli->cli_sock;
167: pfd.events = POLLOUT;
1.3 ! misho 168: if (poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000) == -1 ||
1.2 misho 169: pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
170: LOGERR;
171: e_free(*data);
172: *data = NULL;
173: return -1;
174: }
175: if (send(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
176: LOGERR;
177: e_free(*data);
178: *data = NULL;
179: return -1;
180: }
181:
182: /* receive BLOB from server */
183: pfd.events = POLLIN | POLLPRI;
184: for (ret = AIT_LEN(var), pos = *data; ret > 0; ret -= len, pos += len) {
1.3 ! misho 185: if (poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000) < 1 ||
1.2 misho 186: pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
187: LOGERR;
188: e_free(*data);
189: *data = NULL;
190: return -1;
191: }
192:
193: if ((len = recv(cli->cli_sock, pos, ret, 0)) == -1) {
194: LOGERR;
195: e_free(*data);
196: *data = NULL;
197: return -1;
198: }
199: }
200:
201: /* wait for reply */
202: if ((len = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) < 1 ||
203: pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
204: if (len)
205: LOGERR;
206: else
207: rpc_SetErr(ETIMEDOUT, "Timeout reached! Server not respond");
208: e_free(*data);
209: *data = NULL;
210: return 1;
211: }
212: if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
213: LOGERR;
214: e_free(*data);
215: *data = NULL;
216: return 1;
217: }
218: if (hdr.hdr_cmd != error) {
219: if (ntohl(hdr.hdr_len) != AIT_LEN(var)) {
220: rpc_SetErr(ECANCELED, "Bad return length packet");
221: e_free(*data);
222: *data = NULL;
223: return 1;
224: }
225: }
226:
227: return hdr.hdr_cmd == error;
228: }
229:
230: /*
231: * rpc_cli_delBLOB() - Delete BLOB from server
232: *
233: * @cli = Client instance
234: * @var = BLOB variable
235: * return: -1 error, 0 ok, 1 remote error
236: */
237: int
238: rpc_cli_delBLOB(rpc_cli_t * __restrict cli, ait_val_t * __restrict var)
239: {
240: struct tagBLOBHdr hdr;
241: struct pollfd pfd;
242: int ret;
243:
244: if (!cli || !var) {
245: rpc_SetErr(EINVAL, "Invalid arguments");
246: return -1;
247: } else
248: memset(&hdr, 0, sizeof hdr);
249:
250: rpc_addPktSession(&hdr.hdr_session, cli->cli_parent);
251: hdr.hdr_cmd = unset;
252: hdr.hdr_var = htonl((uint32_t) AIT_GET_BLOB(var));
253: hdr.hdr_ret = 0;
254: hdr.hdr_len = 0;
255:
256: /* send UNSET request */
257: pfd.fd = cli->cli_sock;
258: pfd.events = POLLOUT;
1.3 ! misho 259: if (poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000) == -1 ||
1.2 misho 260: pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
261: LOGERR;
262: return -1;
263: }
264: if (send(cli->cli_sock, &hdr, sizeof hdr, MSG_NOSIGNAL) == -1) {
265: LOGERR;
266: return -1;
267: }
268:
269: /* wait for reply */
270: pfd.events = POLLIN | POLLPRI;
271: if ((ret = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) < 1 ||
272: pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
273: if (ret)
274: LOGERR;
275: else
276: rpc_SetErr(ETIMEDOUT, "Timeout reached! Server not respond");
277: return 1;
278: }
279: if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
280: LOGERR;
281: return 1;
282: }
283:
284: return hdr.hdr_cmd == error;
285: }
286:
287: /*
288: * rpc_cli_getBLOB() - Receive BLOB from server and Delete after that
289: *
290: * @cli = Client instance
291: * @var = BLOB variable
292: * @data = BLOB data, must be e_free after use!
293: * return: -1 error, 0 ok, 1 remote error
294: */
295: int
296: rpc_cli_getBLOB(rpc_cli_t * __restrict cli, ait_val_t * __restrict var, void ** __restrict data)
297: {
298: int ret;
299:
300: ret = rpc_cli_recvBLOB(cli, var, data);
301: ret |= rpc_cli_delBLOB(cli, var) > 0 ? 2 : 0;
302:
303: return ret;
304: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>