--- libaitsess/src/sess.c 2011/04/30 21:35:21 1.2 +++ libaitsess/src/sess.c 2011/09/07 21:06:56 1.3.2.3 @@ -3,9 +3,46 @@ * by Michael Pounov * * $Author: misho $ -* $Id: sess.c,v 1.2 2011/04/30 21:35:21 misho Exp $ +* $Id: sess.c,v 1.3.2.3 2011/09/07 21:06:56 misho Exp $ * -*************************************************************************/ +************************************************************************** +The ELWIX and AITNET software is distributed under the following +terms: + +All of the documentation and software included in the ELWIX and AITNET +Releases is copyrighted by ELWIX - Sofia/Bulgaria + +Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + by Michael Pounov . All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: +This product includes software developed by Michael Pounov +ELWIX - Embedded LightWeight unIX and its contributors. +4. Neither the name of AITNET nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. +*/ #include "global.h" #include "aitsess.h" @@ -15,10 +52,15 @@ * @ppsVals = Array strings * return: none */ -inline void sess_FreeValues(char *** __restrict ppsVals) +inline void +sess_FreeValues(char *** __restrict ppsVals) { char **ptr; + assert(ppsVals); + if (!ppsVals) + return; + for (ptr = *ppsVals; *ptr; ptr++) free(*ptr); free(*ppsVals); @@ -31,7 +73,8 @@ inline void sess_FreeValues(char *** __restrict ppsVal * @ppsVals = Return array strings * return: -1 error: in parameter, !=-1 count of returned strings in ppsVals (must be free after use!) */ -int sess_GetValues(tagSess * __restrict s, char ***ppsVals) +int +sess_GetValues(tagSess * __restrict s, char ***ppsVals) { register int i; char **valz, *Shared = NULL; @@ -87,7 +130,8 @@ int sess_GetValues(tagSess * __restrict s, char ***pps // *{pnLen} input is max_size of buffer & output is really taken bytes * return: 0 not found, -1 error: in parameter, >0 get position, if define item merged with IS_DEF */ -int sess_GetValue(tagSess * __restrict s, const char *csAttr, char *psVal, int *pnLen) +int +sess_GetValue(tagSess * __restrict s, const char *csAttr, char *psVal, int *pnLen) { register int i; int def = IS_VAL; @@ -114,7 +158,7 @@ int sess_GetValue(tagSess * __restrict s, const char * for (i = 1, peer = strtok_r(Shared, MEM_DELIM"\r\n", &p_brk); peer; i++, peer = strtok_r(NULL, MEM_DELIM"\r\n", &p_brk)) { attr = strtok_r(peer, "=\r\n", &a_brk); - if (attr && !strncmp(attr, csAttr, MAX_ATTRIBUTE)) { + if (attr && !strncmp(attr, csAttr, MAX_ATTRIBUTE - 1)) { val = strtok_r(NULL, "=\r\n", &a_brk); if (val && strlen(val)) { if (psVal) @@ -139,11 +183,12 @@ int sess_GetValue(tagSess * __restrict s, const char * * @csAttr = Attribute for erasing * return: 0 Ok, -1 error: in parameter */ -int sess_DelValue(tagSess * __restrict s, const char *csAttr) +int +sess_DelValue(tagSess * __restrict s, const char *csAttr) { register int i; int ret, attrlen; - char *Buffer, *Shared, szAttr[MAX_ATTRIBUTE + 1]; + char *Buffer, *Shared, szAttr[MAX_ATTRIBUTE]; char *peer, *p_brk; if (!s || !csAttr || !*csAttr) @@ -151,9 +196,8 @@ int sess_DelValue(tagSess * __restrict s, const char * else attrlen = strlen(csAttr); Buffer = Shared = NULL; - memset(szAttr, 0, MAX_ATTRIBUTE + 1); - strncpy(szAttr, csAttr, MAX_ATTRIBUTE - 1); - strcat(szAttr, "="); + strlcpy(szAttr, csAttr, sizeof szAttr); + strlcat(szAttr, "=", sizeof szAttr); Buffer = malloc(s->eom); if (!Buffer) { @@ -178,11 +222,10 @@ int sess_DelValue(tagSess * __restrict s, const char * peer[attrlen] == '\r' || peer[attrlen] == '\n') continue; - strcat(Buffer, peer); - strcat(Buffer, MEM_DELIM); + strlcat(Buffer, peer, s->eom); + strlcat(Buffer, MEM_DELIM, s->eom); } - memset(s->addr, 0, s->eom); memcpy(s->addr, Buffer, s->eom); if (s->type == SHARED_MAP) @@ -202,20 +245,20 @@ int sess_DelValue(tagSess * __restrict s, const char * * return: 0 nothing, -1 error: in parameter, >0 set position, if add item merged with IS_ADD and if define item merged with IS_DEF */ -int sess_SetValue(tagSess * __restrict s, const char *csAttr, const char *psVal) +int +sess_SetValue(tagSess * __restrict s, const char *csAttr, const char *psVal) { register int i; int upd, ret, def = IS_VAL; - char *Buffer, *Shared, szAttr[MAX_ATTRIBUTE + 1]; + char *Buffer, *Shared, szAttr[MAX_ATTRIBUTE]; char *peer, *p_brk; if (!s || !csAttr || !*csAttr) return -1; else Buffer = Shared = NULL; - memset(szAttr, 0, MAX_ATTRIBUTE + 1); - strncpy(szAttr, csAttr, MAX_ATTRIBUTE - 1); - strcat(szAttr, "="); + strlcpy(szAttr, csAttr, sizeof szAttr); + strlcat(szAttr, "=", sizeof szAttr); Buffer = malloc(s->eom); if (!Buffer) { @@ -238,35 +281,34 @@ int sess_SetValue(tagSess * __restrict s, const char * if (!strncmp(peer, szAttr, strlen(szAttr))) { upd++; if (psVal) { - strcat(Buffer, szAttr); - strcat(Buffer, psVal); - strcat(Buffer, MEM_DELIM); + strlcat(Buffer, szAttr, s->eom); + strlcat(Buffer, psVal, s->eom); + strlcat(Buffer, MEM_DELIM, s->eom); } else { - strcat(Buffer, csAttr); - strcat(Buffer, MEM_DELIM); + strlcat(Buffer, csAttr, s->eom); + strlcat(Buffer, MEM_DELIM, s->eom); def = IS_DEF; } continue; } - strcat(Buffer, peer); - strcat(Buffer, MEM_DELIM); + strlcat(Buffer, peer, s->eom); + strlcat(Buffer, MEM_DELIM, s->eom); } if (!upd) { if (psVal) { - strcat(Buffer, szAttr); - strcat(Buffer, psVal); - strcat(Buffer, MEM_DELIM); + strlcat(Buffer, szAttr, s->eom); + strlcat(Buffer, psVal, s->eom); + strlcat(Buffer, MEM_DELIM, s->eom); } else { - strcat(Buffer, csAttr); - strcat(Buffer, MEM_DELIM); + strlcat(Buffer, csAttr, s->eom); + strlcat(Buffer, MEM_DELIM, s->eom); def = IS_DEF; } def |= IS_ADD; } - memset(s->addr, 0, s->eom); memcpy(s->addr, Buffer, s->eom); if (s->type == SHARED_MAP) @@ -276,4 +318,111 @@ int sess_SetValue(tagSess * __restrict s, const char * free(Shared); free(Buffer); return upd | def; +} + + +/* + * sess_prepareSession() Attach to shared memory and de-marshaling data + * @s = Session + * @useDirect = Use direct shared memory if !=0 or snapshot of data to array + * return: NULL error or no data, !=NULL array with variables, + * after use must free resources with sess_doneSession() + */ +array_t * +sess_prepareSession(tagSess * __restrict s, u_char useDirect) +{ + array_t *arr = NULL; + sess_hdr_t *hdr; + int ret; + + assert(s); + if (!s) { + sess_SetErr(EINVAL, "Error:: invalid argument\n"); + return NULL; + } + + ATTACH_MEMORY(s); + if (!s->addr) + return NULL; + else + hdr = (sess_hdr_t*) s->addr; + if (hdr->hdr_magic != SESS_AIT_MAGIC) { + DETACH_MEMORY(s); + + sess_SetErr(EINVAL, "Error:: shared memory not contains values with proper format\n"); + return NULL; + } + + DEC_SEMAPHORE(s, ret); + s->zcopy = useDirect; + arr = io_map2vals(s->addr + sizeof(sess_hdr_t), s->eom - sizeof(sess_hdr_t), + hdr->hdr_argc, useDirect); + ADD_SEMAPHORE(s, ret); + + if (!s->zcopy) + DETACH_MEMORY(s); + return arr; +} + +/* + * sess_doneSession() Free resources allocated with sess_prepareSession() + * @s = Session + * @arr = Array with variables for free + * return: none + */ +void +sess_doneSession(tagSess * __restrict s, array_t ** __restrict arr) +{ + assert(s); + if (!s) { + sess_SetErr(EINVAL, "Error:: invalid argument\n"); + return; + } + + if (!s->zcopy) + io_arrayFree(*arr); + else + DETACH_MEMORY(s); + io_arrayDestroy(arr); +} + +/* + * sess_commitSession() Commit data to shared memory + * @s = Session + * @arr = Array with variables for save + * return -1 error or !=-1 size of stored variables into shared memory + */ +int +sess_commitSession(tagSess * __restrict s, array_t * __restrict arr) +{ + sess_hdr_t *hdr; + int rs, ret = 0; + + assert(s && arr); + if (!s || !arr) { + sess_SetErr(EINVAL, "Error:: invalid argument\n"); + return -1; + } + + if (!s->zcopy) + ATTACH_MEMORY(s); + if (!s->addr) { + if (!s->zcopy) + DETACH_MEMORY(s); + + return -1; + } else + hdr = (sess_hdr_t*) s->addr; + + DEC_SEMAPHORE(s, rs); + if ((ret = io_vals2map(s->addr + sizeof(sess_hdr_t), s->eom - sizeof(sess_hdr_t), arr)) != -1) { + hdr->hdr_magic = SESS_AIT_MAGIC; + hdr->hdr_argc = io_arraySize(arr); + ret += sizeof(sess_hdr_t); + } + ADD_SEMAPHORE(s, rs); + + if (!s->zcopy) + DETACH_MEMORY(s); + return ret; }