Annotation of libaitrpc/src/blobcli.c, revision 1.2

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 $
        !             6: * $Id: blobcli.c,v 1.1.2.1 2015/07/02 17:52:53 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 - 2015
        !            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 ((ret = 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 ((ret = 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 ((len = 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 ((ret = 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>