File:  [ELWIX - Embedded LightWeight unIX -] / libaitrpc / src / blobcli.c
Revision 1.3: download - view: text, annotated - select for diffs - revision graph
Wed Mar 20 17:32:31 2024 UTC (4 months ago) by misho
Branches: MAIN
CVS tags: rpc9_6, RPC9_5, HEAD
Version 9.5

    1: /*************************************************************************
    2: * (C) 2015 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
    3: *  by Michael Pounov <misho@openbsd-bg.org>
    4: *
    5: * $Author: misho $
    6: * $Id: blobcli.c,v 1.3 2024/03/20 17:32:31 misho Exp $
    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: 
   15: Copyright 2004 - 2024
   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;
   82: 	if (poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000) == -1 || 
   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;
  168: 	if (poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000) == -1 || 
  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) {
  185: 		if (poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000) < 1 || 
  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;
  259: 	if (poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000) == -1 || 
  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>