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

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

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