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

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

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