Annotation of libaitsess/src/sess.c, revision 1.4

1.2       misho       1: /*************************************************************************
                      2: * (C) 2008 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
                      3: *  by Michael Pounov <misho@openbsd-bg.org>
                      4: *
                      5: * $Author: misho $
1.4     ! misho       6: * $Id: sess.c,v 1.3.2.8 2012/02/10 16:45:36 misho Exp $
1.2       misho       7: *
1.3       misho       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, 2005, 2006, 2007, 2008, 2009, 2010, 2011
                     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: */
1.1       misho      46: #include "global.h"
                     47: #include "aitsess.h"
                     48: 
                     49: 
                     50: /*
1.2       misho      51:  * sess_FreeValues() Free all values from value array allocated from sess_GetValues()
1.4     ! misho      52:  *
1.2       misho      53:  * @ppsVals = Array strings
                     54:  * return: none
1.4     ! misho      55:  */
1.3       misho      56: inline void
                     57: sess_FreeValues(char *** __restrict ppsVals)
1.2       misho      58: {
                     59:        char **ptr;
                     60: 
1.3       misho      61:        assert(ppsVals);
                     62:        if (!ppsVals)
                     63:                return;
                     64: 
1.2       misho      65:        for (ptr = *ppsVals; *ptr; ptr++)
                     66:                free(*ptr);
                     67:        free(*ppsVals);
                     68:        *ppsVals = NULL;
                     69: }
                     70: 
                     71: /*
                     72:  * sess_GetValues() Get all values from session shared memory
1.4     ! misho      73:  *
1.2       misho      74:  * @s = Session item
                     75:  * @ppsVals = Return array strings
                     76:  * return: -1 error: in parameter, !=-1 count of returned strings in ppsVals (must be free after use!)
1.4     ! misho      77:  */
1.3       misho      78: int
1.4     ! misho      79: sess_GetValues(ait_sess_t * __restrict s, char ***ppsVals)
1.2       misho      80: {
                     81:        register int i;
                     82:        char **valz, *Shared = NULL;
                     83:        char *peer, *p_brk;
                     84: 
                     85:        if (!s || !ppsVals)
                     86:                return -1;
                     87:        valz = malloc(sizeof(caddr_t));
                     88:        if (!valz) {
                     89:                LOGERR;
                     90:                return -1;
                     91:        } else
                     92:                *valz = NULL;
                     93: 
                     94:        // allocated memory & mirrored shared memory into this
                     95:        Shared = malloc(s->eom);
                     96:        if (!Shared) {
                     97:                LOGERR;
                     98:                free(valz);
                     99:                return -1;
                    100:        } else
                    101:                memcpy(Shared, s->addr, s->eom);
                    102: 
                    103:        for (i = 0, peer = strtok_r(Shared, MEM_DELIM"\r\n", &p_brk); peer; 
                    104:                        peer = strtok_r(NULL, MEM_DELIM"\r\n", &p_brk)) {
                    105:                if (!strchr(peer, '='))
                    106:                        continue;
                    107:                else
                    108:                        i++;
                    109: 
                    110:                valz = realloc(valz, (i + 1) * sizeof(caddr_t));
                    111:                if (!valz) {
                    112:                        LOGERR;
                    113:                        free(Shared);
                    114:                        return -1;
                    115:                } else
                    116:                        valz[i] = NULL;
                    117: 
                    118:                valz[i - 1] = strdup(peer);
                    119:        }
                    120: 
                    121:        free(Shared);
                    122:        *ppsVals = valz;
                    123:        return i;
                    124: }
                    125: 
                    126: /*
1.1       misho     127:  * sess_GetValue() Get value from session shared memory from attribute
1.4     ! misho     128:  *
1.1       misho     129:  * @s = Session item
                    130:  * @csAttr = Attribute for search
                    131:  * @psVal = Return string buffer
                    132:  * @pnLen = Length of return string buffer, 
                    133:        // *{pnLen} input is max_size of buffer & output is really taken bytes
                    134:  * return: 0 not found, -1 error: in parameter, >0 get position, if define item merged with IS_DEF
1.4     ! misho     135:  */
1.3       misho     136: int
1.4     ! misho     137: sess_GetValue(ait_sess_t * __restrict s, const char *csAttr, char *psVal, int *pnLen)
1.1       misho     138: {
                    139:        register int i;
                    140:        int def = IS_VAL;
                    141:        char *Shared = NULL;
                    142:        char *peer, *p_brk, *a_brk, *attr, *val;
                    143: 
                    144:        if (!s || !csAttr || !*csAttr)
                    145:                return -1;
                    146:        if (psVal) {
                    147:                if (pnLen && *pnLen > 0)
                    148:                        memset(psVal, 0, *pnLen);
                    149:                else
                    150:                        return -1;
                    151:        }
                    152: 
                    153:        // allocated memory & mirrored shared memory into this
                    154:        Shared = malloc(s->eom);
                    155:        if (!Shared) {
                    156:                LOGERR;
                    157:                return -1;
                    158:        } else
                    159:                memcpy(Shared, s->addr, s->eom);
                    160: 
1.2       misho     161:        for (i = 1, peer = strtok_r(Shared, MEM_DELIM"\r\n", &p_brk); peer; 
                    162:                        i++, peer = strtok_r(NULL, MEM_DELIM"\r\n", &p_brk)) {
1.1       misho     163:                attr = strtok_r(peer, "=\r\n", &a_brk);
1.4     ! misho     164:                if (attr && !strncmp(attr, csAttr, MAX_ATTRIBUTE - 1)) {
1.1       misho     165:                        val = strtok_r(NULL, "=\r\n", &a_brk);
                    166:                        if (val && strlen(val)) {
                    167:                                if (psVal)
1.2       misho     168:                                        strlcpy(psVal, val, *pnLen);
1.1       misho     169:                                if (pnLen)
                    170:                                        *pnLen = strlen(val);
                    171:                        } else
                    172:                                def = IS_DEF;
                    173: 
                    174:                        free(Shared);
                    175:                        return i | def;
                    176:                }
                    177:        }
                    178: 
                    179:        free(Shared);
                    180:        return 0;
                    181: }
                    182: 
                    183: /*
                    184:  * sess_DelValue() Delete item from session shared memory
1.4     ! misho     185:  *
1.1       misho     186:  * @s = Session item
                    187:  * @csAttr = Attribute for erasing
                    188:  * return: 0 Ok, -1 error: in parameter
1.4     ! misho     189:  */
1.3       misho     190: int
1.4     ! misho     191: sess_DelValue(ait_sess_t * __restrict s, const char *csAttr)
1.1       misho     192: {
                    193:        register int i;
1.4     ! misho     194:        int attrlen;
        !           195:        char *Buffer, *Shared, szAttr[MAX_ATTRIBUTE];
1.1       misho     196:        char *peer, *p_brk;
                    197: 
                    198:        if (!s || !csAttr || !*csAttr)
                    199:                return -1;
                    200:        else
                    201:                attrlen = strlen(csAttr);
                    202:        Buffer = Shared = NULL;
1.4     ! misho     203:        strlcpy(szAttr, csAttr, sizeof szAttr);
        !           204:        strlcat(szAttr, "=", sizeof szAttr);
1.1       misho     205: 
                    206:        Buffer = malloc(s->eom);
                    207:        if (!Buffer) {
                    208:                LOGERR;
                    209:                return -1;
                    210:        } else
                    211:                memset(Buffer, 0, s->eom);
                    212:        Shared = malloc(s->eom);
                    213:        if (!Shared) {
                    214:                LOGERR;
                    215:                free(Buffer);
                    216:                return -1;
                    217:        } else {
1.4     ! misho     218:                DEC_SEM(s);
1.1       misho     219:                memcpy(Shared, s->addr, s->eom);
                    220:        }
                    221: 
1.2       misho     222:        for (i = 1, peer = strtok_r(Shared, MEM_DELIM"\r\n", &p_brk); peer; 
                    223:                        i++, peer = strtok_r(NULL, MEM_DELIM"\r\n", &p_brk)) {
1.1       misho     224:                if (!strncmp(peer, csAttr, attrlen))
1.2       misho     225:                        if (peer[attrlen] == '=' || peer[attrlen] == *MEM_DELIM || !peer[attrlen] ||
1.1       misho     226:                                        peer[attrlen] == '\r' || peer[attrlen] == '\n')
                    227:                                continue;
                    228: 
1.4     ! misho     229:                strlcat(Buffer, peer, s->eom);
        !           230:                strlcat(Buffer, MEM_DELIM, s->eom);
1.1       misho     231:        }
                    232: 
                    233:        memcpy(s->addr, Buffer, s->eom);
                    234: 
                    235:        if (s->type == SHARED_MAP)
                    236:                msync(s->addr, 0, MS_SYNC | MS_INVALIDATE);
                    237: 
1.4     ! misho     238:        INC_SEM(s);
1.1       misho     239:        free(Shared);
                    240:        free(Buffer);
                    241:        return 0;
                    242: }
                    243: 
                    244: /*
                    245:  * sess_SetValue() Set item into session shared memory or update if find it
1.4     ! misho     246:  *
1.1       misho     247:  * @s = Session item
                    248:  * @csAttr = Attribute
                    249:  * @psVal = Value
                    250:  * return: 0 nothing, -1 error: in parameter, 
                    251:        >0 set position, if add item merged with IS_ADD and if define item merged with IS_DEF
1.4     ! misho     252:  */
1.3       misho     253: int
1.4     ! misho     254: sess_SetValue(ait_sess_t * __restrict s, const char *csAttr, const char *psVal)
1.1       misho     255: {
                    256:        register int i;
1.4     ! misho     257:        int upd, def = IS_VAL;
        !           258:        char *Buffer, *Shared, szAttr[MAX_ATTRIBUTE];
1.1       misho     259:        char *peer, *p_brk;
                    260: 
                    261:        if (!s || !csAttr || !*csAttr)
                    262:                return -1;
                    263:        else
                    264:                Buffer = Shared = NULL;
1.4     ! misho     265:        strlcpy(szAttr, csAttr, sizeof szAttr);
        !           266:        strlcat(szAttr, "=", sizeof szAttr);
1.1       misho     267: 
                    268:        Buffer = malloc(s->eom);
                    269:        if (!Buffer) {
                    270:                LOGERR;
                    271:                return -1;
                    272:        } else
                    273:                memset(Buffer, 0, s->eom);
                    274:        Shared = malloc(s->eom);
                    275:        if (!Shared) {
                    276:                LOGERR;
                    277:                free(Buffer);
                    278:                return -1;
                    279:        } else {
1.4     ! misho     280:                DEC_SEM(s);
1.1       misho     281:                memcpy(Shared, s->addr, s->eom);
                    282:        }
                    283: 
1.2       misho     284:        for (i = 1, upd = 0, peer = strtok_r(Shared, MEM_DELIM"\r\n", &p_brk); peer; 
                    285:                        i++, peer = strtok_r(NULL, MEM_DELIM"\r\n", &p_brk)) {
1.1       misho     286:                if (!strncmp(peer, szAttr, strlen(szAttr))) {
                    287:                        upd++;
                    288:                        if (psVal) {
1.4     ! misho     289:                                strlcat(Buffer, szAttr, s->eom);
        !           290:                                strlcat(Buffer, psVal, s->eom);
        !           291:                                strlcat(Buffer, MEM_DELIM, s->eom);
1.1       misho     292:                        } else {
1.4     ! misho     293:                                strlcat(Buffer, csAttr, s->eom);
        !           294:                                strlcat(Buffer, MEM_DELIM, s->eom);
1.1       misho     295:                                def = IS_DEF;
                    296:                        }
                    297:                        continue;
                    298:                }
                    299: 
1.4     ! misho     300:                strlcat(Buffer, peer, s->eom);
        !           301:                strlcat(Buffer, MEM_DELIM, s->eom);
1.1       misho     302:        }
                    303: 
                    304:        if (!upd) {
                    305:                if (psVal) {
1.4     ! misho     306:                        strlcat(Buffer, szAttr, s->eom);
        !           307:                        strlcat(Buffer, psVal, s->eom);
        !           308:                        strlcat(Buffer, MEM_DELIM, s->eom);
1.1       misho     309:                } else {
1.4     ! misho     310:                        strlcat(Buffer, csAttr, s->eom);
        !           311:                        strlcat(Buffer, MEM_DELIM, s->eom);
1.1       misho     312:                        def = IS_DEF;
                    313:                }
                    314:                def |= IS_ADD;
                    315:        }
                    316: 
                    317:        memcpy(s->addr, Buffer, s->eom);
                    318: 
                    319:        if (s->type == SHARED_MAP)
                    320:                msync(s->addr, 0, MS_SYNC | MS_INVALIDATE);
                    321: 
1.4     ! misho     322:        INC_SEM(s);
1.1       misho     323:        free(Shared);
                    324:        free(Buffer);
                    325:        return upd | def;
                    326: }
1.4     ! misho     327: 
        !           328: 
        !           329: /*
        !           330:  * sess_prepareSession() Attach to shared memory and de-marshaling data
        !           331:  *
        !           332:  * @s = Session
        !           333:  * @useDirect = Use direct shared memory if !=0 or snapshot of data to array
        !           334:  * return: NULL error or no data, !=NULL array with variables, 
        !           335:  *             after use must free resources with sess_doneSession()
        !           336:  */
        !           337: array_t *
        !           338: sess_prepareSession(ait_sess_t * __restrict s, char useDirect)
        !           339: {
        !           340:        array_t *arr = NULL;
        !           341:        sess_hdr_t *hdr;
        !           342: 
        !           343:        assert(s);
        !           344:        if (!s) {
        !           345:                sess_SetErr(EINVAL, "Error:: invalid argument\n");
        !           346:                return NULL;
        !           347:        }
        !           348:        if (s->addr) {
        !           349:                sess_SetErr(EINVAL, "Error:: already attached memory\n");
        !           350:                return NULL;
        !           351:        }
        !           352: 
        !           353:        ATTACH_MEMORY(s);
        !           354:        if (!s->addr)
        !           355:                return NULL;
        !           356:        else
        !           357:                hdr = (sess_hdr_t*) s->addr;
        !           358:        if (hdr->hdr_magic != SESS_AIT_MAGIC) {
        !           359:                DETACH_MEMORY(s);
        !           360: 
        !           361:                sess_SetErr(EINVAL, "Error:: shared memory not contains values with proper format\n");
        !           362:                return NULL;
        !           363:        }
        !           364: 
        !           365:        DEC_SEM(s);
        !           366:        s->zcpy = useDirect;
        !           367:        arr = io_map2vars(s->addr + sizeof(sess_hdr_t), s->eom - sizeof(sess_hdr_t), 
        !           368:                        hdr->hdr_argc, useDirect);
        !           369:        INC_SEM(s);
        !           370: 
        !           371:        if (!s->zcpy)
        !           372:                DETACH_MEMORY(s);
        !           373:        return arr;
        !           374: }
        !           375: 
        !           376: /*
        !           377:  * sess_doneSession() Free resources allocated with sess_prepareSession()
        !           378:  *
        !           379:  * @s = Session
        !           380:  * @arr = Array with variables for free
        !           381:  * return: none
        !           382:  */
        !           383: void
        !           384: sess_doneSession(ait_sess_t * __restrict s, array_t ** __restrict arr)
        !           385: {
        !           386:        assert(s);
        !           387:        if (!s) {
        !           388:                sess_SetErr(EINVAL, "Error:: invalid argument\n");
        !           389:                return;
        !           390:        }
        !           391: 
        !           392:        if (!s->zcpy)
        !           393:                io_arrayFree(*arr);
        !           394:        else
        !           395:                DETACH_MEMORY(s);
        !           396:        io_arrayDestroy(arr);
        !           397: }
        !           398: 
        !           399: /*
        !           400:  * sess_commitSession() Commit data to shared memory
        !           401:  *
        !           402:  * @s = Session
        !           403:  * @arr = Array with variables for save
        !           404:  * return -1 error or !=-1 size of stored variables into shared memory
        !           405:  */
        !           406: int
        !           407: sess_commitSession(ait_sess_t * __restrict s, array_t * __restrict arr)
        !           408: {
        !           409:        sess_hdr_t *hdr;
        !           410:        int ret = 0;
        !           411: 
        !           412:        assert(s && arr);
        !           413:        if (!s || !arr) {
        !           414:                sess_SetErr(EINVAL, "Error:: invalid argument\n");
        !           415:                return -1;
        !           416:        }
        !           417: 
        !           418:        ATTACH_MEMORY(s);
        !           419:        if (!s->addr) {
        !           420:                DETACH_MEMORY(s);
        !           421:                return -1;
        !           422:        } else
        !           423:                hdr = (sess_hdr_t*) s->addr;
        !           424: 
        !           425:        DEC_SEM(s);
        !           426:        if ((ret = io_vars2map(s->addr + sizeof(sess_hdr_t), s->eom - sizeof(sess_hdr_t), arr)) != -1) {
        !           427:                hdr->hdr_magic = SESS_AIT_MAGIC;
        !           428:                hdr->hdr_argc = io_arraySize(arr);
        !           429:                ret += sizeof(sess_hdr_t);
        !           430:        }
        !           431:        INC_SEM(s);
        !           432: 
        !           433:        DETACH_MEMORY(s);
        !           434:        return ret;
        !           435: }

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