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

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

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