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

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