Annotation of libaitrpc/src/blob.c, revision 1.10

1.2       misho       1: /*************************************************************************
                      2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
                      3: *  by Michael Pounov <misho@openbsd-bg.org>
                      4: *
                      5: * $Author: misho $
1.10    ! misho       6: * $Id: blob.c,v 1.9.2.1 2012/08/06 15:01:55 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.5       misho      15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
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: /*
1.8       misho      50:  * rpc_srv_blobCreate() - Create and map blob to memory region and return object
1.5       misho      51:  *
1.2       misho      52:  * @srv = RPC Server instance
                     53:  * @len = BLOB length object
                     54:  * return: NULL error or !=NULL allocated BLOB object
                     55:  */
                     56: inline rpc_blob_t *
                     57: rpc_srv_blobCreate(rpc_srv_t * __restrict srv, int len)
                     58: {
                     59:        rpc_blob_t *blob = NULL;
                     60:        char szFName[MAXPATHLEN];
                     61:        int f;
                     62:        u_int rnd;
                     63: 
                     64: again:
                     65:        rnd = random() % UINT_MAX;
                     66: 
1.3       misho      67:        memset(szFName, 0, sizeof szFName);
1.10    ! misho      68:        snprintf(szFName, sizeof szFName, BLOB_FILE, AIT_GET_STRZ(&srv->srv_blob.dir), rnd);
1.2       misho      69:        f = open(szFName, O_CREAT | O_EXCL | O_RDWR, 0600);
                     70:        if (f == -1) {
                     71:                if (errno == EEXIST)
                     72:                        goto again;
                     73: 
                     74:                LOGERR;
                     75:                return NULL;
                     76:        }
1.8       misho      77:        if (ftruncate(f, len) == -1) {
1.2       misho      78:                LOGERR;
                     79:                close(f);
                     80:                unlink(szFName);
                     81:                return NULL;
1.8       misho      82:        }
1.2       misho      83: 
1.9       misho      84:        blob = io_malloc(sizeof(rpc_blob_t));
1.2       misho      85:        if (!blob) {
                     86:                LOGERR;
                     87:                close(f);
                     88:                unlink(szFName);
                     89:                return NULL;
                     90:        }
                     91: 
                     92:        blob->blob_data = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, f, 0);
                     93:        if (blob->blob_data == MAP_FAILED) {
                     94:                LOGERR;
1.9       misho      95:                io_free(blob);
1.2       misho      96:                close(f);
                     97:                unlink(szFName);
                     98:                return NULL;
                     99:        } else
                    100:                close(f);
                    101: 
                    102:        blob->blob_len = len;
                    103:        blob->blob_var = rnd;
                    104:        return blob;
                    105: }
                    106: 
                    107: /*
1.5       misho     108:  * rpc_srv_blobMap() - Map blob to memory region 
                    109:  *
1.2       misho     110:  * @srv = RPC Server instance
                    111:  * @blob = Map to this BLOB element
                    112:  * return: -1 error or 0 ok
                    113:  */
                    114: inline int
                    115: rpc_srv_blobMap(rpc_srv_t * __restrict srv, rpc_blob_t * __restrict blob)
                    116: {
                    117:        int f;
                    118:        char szFName[MAXPATHLEN];
                    119: 
                    120:        if (!blob) {
1.5       misho     121:                rpc_SetErr(EINVAL, "Invalid argument BLOB");
1.2       misho     122:                return -1;
                    123:        }
1.4       misho     124:        if (blob->blob_data) {
1.5       misho     125:                rpc_SetErr(EPERM, "Already mmapped object found!");
1.4       misho     126:                return -1;
                    127:        }
1.2       misho     128: 
1.3       misho     129:        memset(szFName, 0, sizeof szFName);
1.10    ! misho     130:        snprintf(szFName, sizeof szFName, BLOB_FILE, AIT_GET_STRZ(&srv->srv_blob.dir), blob->blob_var);
1.2       misho     131:        f = open(szFName, O_RDWR);
                    132:        if (f == -1) {
                    133:                LOGERR;
                    134:                return -1;
                    135:        }
                    136: 
                    137:        blob->blob_data = mmap(NULL, blob->blob_len, PROT_READ | PROT_WRITE, MAP_SHARED, f, 0);
                    138:        if (blob->blob_data == MAP_FAILED) {
                    139:                LOGERR;
                    140:                close(f);
                    141:                blob->blob_data = NULL;
                    142:                return -1;
                    143:        } else {
                    144:                close(f);
                    145: 
                    146:                madvise(blob->blob_data, blob->blob_len, MADV_SEQUENTIAL);
                    147:        }
                    148: 
                    149:        return 0;
                    150: }
                    151: 
                    152: /*
1.5       misho     153:  * rpc_srv_blobUnmap() - Unmap blob memory region 
                    154:  *
1.2       misho     155:  * @blob = Mapped BLOB element
                    156:  * return: none
                    157:  */
                    158: inline void
                    159: rpc_srv_blobUnmap(rpc_blob_t * __restrict blob)
                    160: {
1.8       misho     161:        if (blob && blob->blob_data) {
1.2       misho     162:                munmap(blob->blob_data, blob->blob_len);
                    163:                blob->blob_data = NULL;
                    164:        }
                    165: }
                    166: 
                    167: /*
1.5       misho     168:  * rpc_srv_blobFree() - Free blob from disk & memory
                    169:  *
1.2       misho     170:  * @srv = RPC Server instance
                    171:  * @blob = Mapped BLOB element
                    172:  * return: -1 error or 0 ok
                    173:  */
                    174: inline int
                    175: rpc_srv_blobFree(rpc_srv_t * __restrict srv, rpc_blob_t * __restrict blob)
                    176: {
                    177:        char szFName[MAXPATHLEN];
                    178: 
                    179:        if (!blob) {
1.5       misho     180:                rpc_SetErr(EINVAL, "Invalid argument BLOB");
1.2       misho     181:                return -1;
1.8       misho     182:        } else
1.2       misho     183:                rpc_srv_blobUnmap(blob);
                    184: 
1.3       misho     185:        memset(szFName, 0, sizeof szFName);
1.10    ! misho     186:        snprintf(szFName, sizeof szFName, BLOB_FILE, AIT_GET_STRZ(&srv->srv_blob.dir), blob->blob_var);
1.3       misho     187:        if (unlink(szFName) == -1) {
1.2       misho     188:                LOGERR;
                    189:                return -1;
                    190:        }
                    191: 
                    192:        return 0;
                    193: }
                    194: 
1.8       misho     195: /* ------------------------------------------------------------ */
1.2       misho     196: 
                    197: /*
1.5       misho     198:  * rpc_srv_sendBLOB() - Send mapped BLOB to client
                    199:  *
1.2       misho     200:  * @cli = Client instance
                    201:  * @blob = Mapped BLOB element
                    202:  * return: -1 error, 0 ok
                    203:  */
                    204: int
                    205: rpc_srv_sendBLOB(rpc_cli_t * __restrict cli, rpc_blob_t * __restrict blob)
                    206: {
                    207:        int ret, len;
                    208:        uint8_t *pos;
                    209: 
                    210:        if (!cli || !blob || !blob->blob_data) {
1.5       misho     211:                rpc_SetErr(EINVAL, "Invalid arguments");
1.2       misho     212:                return -1;
                    213:        }
                    214: 
1.3       misho     215:        for (ret = blob->blob_len, pos = blob->blob_data; ret > 0; ret -= len, pos += len) {
1.8       misho     216:                len = send(cli->cli_sock, pos, ret, MSG_NOSIGNAL);
1.3       misho     217:                if (len == -1) {
1.2       misho     218:                        LOGERR;
                    219:                        return -1;
                    220:                }
1.3       misho     221:        }
1.2       misho     222: 
                    223:        return ret;
                    224: }
                    225: 
                    226: /*
1.5       misho     227:  * rpc_srv_recvBLOB() - Receive BLOB from client
                    228:  *
1.2       misho     229:  * @cli = Client instance
                    230:  * @blob = Mapped BLOB element
                    231:  * return: -1 error, 0 ok, >0 unreceived data from client, may be error?
                    232:  */
                    233: int
                    234: rpc_srv_recvBLOB(rpc_cli_t * __restrict cli, rpc_blob_t * __restrict blob)
                    235: {
                    236:        int ret, len;
                    237:        uint8_t *pos;
1.7       misho     238:        struct pollfd pfd;
1.2       misho     239: 
                    240:        if (!cli || !blob || !blob->blob_data) {
1.5       misho     241:                rpc_SetErr(EINVAL, "Invalid arguments");
1.2       misho     242:                return -1;
1.7       misho     243:        }
1.2       misho     244: 
1.7       misho     245:        pfd.fd = cli->cli_sock;
                    246:        pfd.events = POLLIN | POLLPRI;
1.2       misho     247:        for (ret = blob->blob_len, pos = blob->blob_data; ret > 0; ret -= len, pos += len) {
1.8       misho     248:                if ((len = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) < 1 || 
1.7       misho     249:                                pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
1.8       misho     250:                        if (len)
                    251:                                LOGERR;
                    252:                        else
                    253:                                rpc_SetErr(ETIMEDOUT, "Timeout reached! Server not respond");
1.2       misho     254:                        return -1;
                    255:                }
                    256: 
1.3       misho     257:                len = recv(cli->cli_sock, pos, ret, 0);
                    258:                if (len == -1) {
1.2       misho     259:                        LOGERR;
                    260:                        return -1;
                    261:                }
                    262:        }
                    263: 
                    264:        return ret;
                    265: }
                    266: 
1.8       misho     267: /* ------------------------------------------------------------ */
1.2       misho     268: 
                    269: /*
1.5       misho     270:  * rpc_cli_sendBLOB() - Send BLOB to server
                    271:  *
1.2       misho     272:  * @cli = Client instance
                    273:  * @var = BLOB variable
                    274:  * @data = BLOB data
                    275:  * return: -1 error, 0 ok, 1 remote error
                    276:  */
                    277: int
1.4       misho     278: rpc_cli_sendBLOB(rpc_cli_t * __restrict cli, ait_val_t * __restrict var, void * __restrict data)
1.2       misho     279: {
                    280:        int ret, len;
                    281:        uint8_t *pos;
                    282:        struct tagBLOBHdr hdr;
1.7       misho     283:        struct pollfd pfd;
1.2       misho     284: 
                    285:        if (!cli || !var || !data) {
1.5       misho     286:                rpc_SetErr(EINVAL, "Invalid arguments");
1.2       misho     287:                return -1;
1.8       misho     288:        } else
                    289:                memset(&hdr, 0, sizeof hdr);
1.2       misho     290: 
1.5       misho     291:        rpc_addPktSession(&hdr.hdr_session, cli->cli_parent);
1.2       misho     292:        hdr.hdr_cmd = set;
                    293:        hdr.hdr_var = 0;
                    294:        hdr.hdr_ret = 0;
1.5       misho     295:        hdr.hdr_len = htonl(AIT_LEN(var));
                    296:        /* calculate CRC */
                    297:        hdr.hdr_crc ^= hdr.hdr_crc;
1.6       misho     298:        hdr.hdr_crc = htons(crcFletcher16((u_short*) &hdr, sizeof hdr / 2));
1.5       misho     299: 
                    300:        /* send SET request */
1.8       misho     301:        pfd.fd = cli->cli_sock;
                    302:        pfd.events = POLLOUT;
                    303:        if ((ret = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) == -1 || 
                    304:                        pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
                    305:                LOGERR;
                    306:                return -1;
                    307:        }
                    308:        if (send(cli->cli_sock, &hdr, sizeof hdr, MSG_NOSIGNAL) == -1) {
1.2       misho     309:                LOGERR;
                    310:                return -1;
                    311:        }
                    312: 
1.4       misho     313:        /* send BLOB to server */
                    314:        for (ret = AIT_LEN(var), pos = data; ret > 0; ret -= len, pos += len)
1.8       misho     315:                if ((len = send(cli->cli_sock, pos, ret, MSG_NOSIGNAL)) == -1) {
1.2       misho     316:                        LOGERR;
                    317:                        return -1;
                    318:                }
                    319: 
1.5       misho     320:        /* wait for reply */
1.7       misho     321:        pfd.events = POLLIN | POLLPRI;
1.8       misho     322:        if ((ret = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) < 1 || 
1.7       misho     323:                        pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
                    324:                if (ret)
1.2       misho     325:                        LOGERR;
1.7       misho     326:                else
                    327:                        rpc_SetErr(ETIMEDOUT, "Timeout reached! Server not respond");
                    328:                return -1;
1.2       misho     329:        }
                    330:        if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
                    331:                LOGERR;
1.5       misho     332:                return 1;
                    333:        }
                    334:        /* check CRC */
                    335:        ret = ntohs(hdr.hdr_crc);
                    336:        hdr.hdr_crc ^= hdr.hdr_crc;
1.6       misho     337:        if (ret != crcFletcher16((u_short*) &hdr, sizeof hdr / 2)) {
1.5       misho     338:                rpc_SetErr(ERPCMISMATCH, "Bad CRC BLOB packet");
                    339:                return 1;
1.2       misho     340:        }
1.5       misho     341: 
1.2       misho     342:        if (hdr.hdr_cmd != error) {
1.5       misho     343:                if (ntohl(hdr.hdr_len) != AIT_LEN(var)) {
                    344:                        rpc_SetErr(ECANCELED, "Bad return length packet");
                    345:                        return 1;
1.2       misho     346:                }
                    347: 
1.8       misho     348:                AIT_SET_BLOB(var, ntohl(hdr.hdr_var), ntohl(hdr.hdr_len));
1.2       misho     349:        }
                    350: 
                    351:        return hdr.hdr_cmd == error;
                    352: }
                    353: 
                    354: /*
1.5       misho     355:  * rpc_cli_recvBLOB() - Receive BLOB from server
                    356:  *
1.2       misho     357:  * @cli = Client instance
                    358:  * @var = BLOB variable
1.9       misho     359:  * @data = BLOB data, must be io_free after use!
1.2       misho     360:  * return: -1 error, 0 ok, 1 remote error
                    361:  */
                    362: int
1.4       misho     363: rpc_cli_recvBLOB(rpc_cli_t * __restrict cli, ait_val_t * __restrict var, void ** __restrict data)
1.2       misho     364: {
                    365:        int ret, len;
                    366:        uint8_t *pos;
1.7       misho     367:        struct pollfd pfd;
1.2       misho     368:        struct tagBLOBHdr hdr;
                    369: 
                    370:        if (!cli || !var || !data) {
1.5       misho     371:                rpc_SetErr(EINVAL, "Invalid arguments");
1.2       misho     372:                return -1;
1.7       misho     373:        }
1.2       misho     374: 
1.9       misho     375:        *data = io_malloc(AIT_LEN(var));
1.2       misho     376:        if (!*data) {
                    377:                LOGERR;
                    378:                return -1;
1.8       misho     379:        } else {
                    380:                memset(&hdr, 0, sizeof hdr);
1.4       misho     381:                memset(*data, 0, AIT_LEN(var));
1.8       misho     382:        }
1.2       misho     383: 
1.5       misho     384:        rpc_addPktSession(&hdr.hdr_session, cli->cli_parent);
1.2       misho     385:        hdr.hdr_cmd = get;
1.5       misho     386:        hdr.hdr_var = htonl((uint32_t) AIT_GET_BLOB(var));
1.2       misho     387:        hdr.hdr_ret = 0;
                    388:        hdr.hdr_len = 0;
1.5       misho     389:        /* calculate CRC */
                    390:        hdr.hdr_crc ^= hdr.hdr_crc;
1.6       misho     391:        hdr.hdr_crc = htons(crcFletcher16((u_short*) &hdr, sizeof hdr / 2));
1.5       misho     392: 
                    393:        /* send GET request */
1.8       misho     394:        pfd.fd = cli->cli_sock;
                    395:        pfd.events = POLLOUT;
                    396:        if ((ret = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) == -1 || 
                    397:                        pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
                    398:                LOGERR;
1.9       misho     399:                io_free(*data);
1.8       misho     400:                *data = NULL;
                    401:                return -1;
                    402:        }
1.2       misho     403:        if (send(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
                    404:                LOGERR;
1.9       misho     405:                io_free(*data);
1.2       misho     406:                *data = NULL;
                    407:                return -1;
                    408:        }
                    409: 
1.4       misho     410:        /* receive BLOB from server */
1.7       misho     411:        pfd.events = POLLIN | POLLPRI;
1.4       misho     412:        for (ret = AIT_LEN(var), pos = *data; ret > 0; ret -= len, pos += len) {
1.8       misho     413:                if ((len = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) < 1 || 
1.7       misho     414:                                pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
1.2       misho     415:                        LOGERR;
1.9       misho     416:                        io_free(*data);
1.2       misho     417:                        *data = NULL;
                    418:                        return -1;
                    419:                }
                    420: 
1.3       misho     421:                if ((len = recv(cli->cli_sock, pos, ret, 0)) == -1) {
1.2       misho     422:                        LOGERR;
1.9       misho     423:                        io_free(*data);
1.2       misho     424:                        *data = NULL;
                    425:                        return -1;
                    426:                }
                    427:        }
                    428: 
1.5       misho     429:        /* wait for reply */
1.8       misho     430:        if ((len = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) < 1 || 
1.7       misho     431:                        pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
                    432:                if (len)
1.2       misho     433:                        LOGERR;
1.7       misho     434:                else
                    435:                        rpc_SetErr(ETIMEDOUT, "Timeout reached! Server not respond");
1.9       misho     436:                io_free(*data);
1.7       misho     437:                *data = NULL;
                    438:                return 1;
1.2       misho     439:        }
                    440:        if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
                    441:                LOGERR;
1.9       misho     442:                io_free(*data);
1.2       misho     443:                *data = NULL;
1.5       misho     444:                return 1;
                    445:        }
                    446:        /* check CRC */
                    447:        ret = ntohs(hdr.hdr_crc);
                    448:        hdr.hdr_crc ^= hdr.hdr_crc;
1.6       misho     449:        if (ret != crcFletcher16((u_short*) &hdr, sizeof hdr / 2)) {
1.5       misho     450:                rpc_SetErr(ERPCMISMATCH, "Bad CRC BLOB packet");
1.9       misho     451:                io_free(*data);
1.5       misho     452:                *data = NULL;
                    453:                return 1;
1.2       misho     454:        }
                    455:        if (hdr.hdr_cmd != error) {
1.5       misho     456:                if (ntohl(hdr.hdr_len) != AIT_LEN(var)) {
                    457:                        rpc_SetErr(ECANCELED, "Bad return length packet");
1.9       misho     458:                        io_free(*data);
1.2       misho     459:                        *data = NULL;
1.5       misho     460:                        return 1;
1.2       misho     461:                }
                    462:        }
                    463: 
                    464:        return hdr.hdr_cmd == error;
                    465: }
                    466: 
                    467: /*
1.5       misho     468:  * rpc_cli_delBLOB() - Delete BLOB from server
                    469:  *
1.2       misho     470:  * @cli = Client instance
                    471:  * @var = BLOB variable
                    472:  * return: -1 error, 0 ok, 1 remote error
                    473:  */
                    474: int
1.4       misho     475: rpc_cli_delBLOB(rpc_cli_t * __restrict cli, ait_val_t * __restrict var)
1.2       misho     476: {
                    477:        struct tagBLOBHdr hdr;
1.7       misho     478:        struct pollfd pfd;
1.5       misho     479:        int ret;
1.2       misho     480: 
                    481:        if (!cli || !var) {
1.5       misho     482:                rpc_SetErr(EINVAL, "Invalid arguments");
1.2       misho     483:                return -1;
1.8       misho     484:        } else
                    485:                memset(&hdr, 0, sizeof hdr);
1.2       misho     486: 
1.5       misho     487:        rpc_addPktSession(&hdr.hdr_session, cli->cli_parent);
1.2       misho     488:        hdr.hdr_cmd = unset;
1.5       misho     489:        hdr.hdr_var = htonl((uint32_t) AIT_GET_BLOB(var));
1.2       misho     490:        hdr.hdr_ret = 0;
                    491:        hdr.hdr_len = 0;
1.5       misho     492:        /* calculate CRC */
                    493:        hdr.hdr_crc ^= hdr.hdr_crc;
1.6       misho     494:        hdr.hdr_crc = htons(crcFletcher16((u_short*) &hdr, sizeof hdr / 2));
1.5       misho     495: 
                    496:        /* send UNSET request */
1.8       misho     497:        pfd.fd = cli->cli_sock;
                    498:        pfd.events = POLLOUT;
                    499:        if ((ret = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) == -1 || 
                    500:                        pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
                    501:                LOGERR;
                    502:                return -1;
                    503:        }
                    504:        if (send(cli->cli_sock, &hdr, sizeof hdr, MSG_NOSIGNAL) == -1) {
1.2       misho     505:                LOGERR;
                    506:                return -1;
                    507:        }
                    508: 
1.5       misho     509:        /* wait for reply */
1.7       misho     510:        pfd.events = POLLIN | POLLPRI;
1.8       misho     511:        if ((ret = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) < 1 || 
1.7       misho     512:                        pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
                    513:                if (ret)
1.2       misho     514:                        LOGERR;
1.7       misho     515:                else
                    516:                        rpc_SetErr(ETIMEDOUT, "Timeout reached! Server not respond");
                    517:                return 1;
1.2       misho     518:        }
                    519:        if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
                    520:                LOGERR;
1.5       misho     521:                return 1;
                    522:        }
                    523:        /* check CRC */
                    524:        ret = ntohs(hdr.hdr_crc);
                    525:        hdr.hdr_crc ^= hdr.hdr_crc;
1.6       misho     526:        if (ret != crcFletcher16((u_short*) &hdr, sizeof hdr / 2)) {
1.5       misho     527:                rpc_SetErr(ERPCMISMATCH, "Bad CRC BLOB packet");
                    528:                return 1;
1.2       misho     529:        }
                    530: 
                    531:        return hdr.hdr_cmd == error;
                    532: }
                    533: 
                    534: /*
1.5       misho     535:  * rpc_cli_getBLOB() - Receive BLOB from server and Delete after that
                    536:  *
1.2       misho     537:  * @cli = Client instance
                    538:  * @var = BLOB variable
1.9       misho     539:  * @data = BLOB data, must be io_free after use!
1.2       misho     540:  * return: -1 error, 0 ok, 1 remote error
                    541:  */
                    542: inline int
1.4       misho     543: rpc_cli_getBLOB(rpc_cli_t * __restrict cli, ait_val_t * __restrict var, void ** __restrict data)
1.2       misho     544: {
                    545:        int ret;
                    546: 
                    547:        ret = rpc_cli_recvBLOB(cli, var, data);
                    548:        ret |= rpc_cli_delBLOB(cli, var) > 0 ? 2 : 0;
                    549: 
                    550:        return ret;
                    551: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>