File:  [ELWIX - Embedded LightWeight unIX -] / libaitsess / src / sess.c
Revision 1.3.2.8: download - view: text, annotated - select for diffs - revision graph
Fri Feb 10 16:45:36 2012 UTC (12 years, 4 months ago) by misho
Branches: sess3_0
Diff to: branchpoint 1.3: preferred, unified
Major changes and refactoring ...
 - Change API all calls
 - Redesign of ELWIX sessions
 - change macros
 - change session structures
 and etc ...

    1: /*************************************************************************
    2: * (C) 2008 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
    3: *  by Michael Pounov <misho@openbsd-bg.org>
    4: *
    5: * $Author: misho $
    6: * $Id: sess.c,v 1.3.2.8 2012/02/10 16:45:36 misho Exp $
    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: 
   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: */
   46: #include "global.h"
   47: #include "aitsess.h"
   48: 
   49: 
   50: /*
   51:  * sess_FreeValues() Free all values from value array allocated from sess_GetValues()
   52:  *
   53:  * @ppsVals = Array strings
   54:  * return: none
   55:  */
   56: inline void
   57: sess_FreeValues(char *** __restrict ppsVals)
   58: {
   59: 	char **ptr;
   60: 
   61: 	assert(ppsVals);
   62: 	if (!ppsVals)
   63: 		return;
   64: 
   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
   73:  *
   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!)
   77:  */
   78: int
   79: sess_GetValues(ait_sess_t * __restrict s, char ***ppsVals)
   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: /*
  127:  * sess_GetValue() Get value from session shared memory from attribute
  128:  *
  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
  135:  */
  136: int
  137: sess_GetValue(ait_sess_t * __restrict s, const char *csAttr, char *psVal, int *pnLen)
  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: 
  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)) {
  163: 		attr = strtok_r(peer, "=\r\n", &a_brk);
  164: 		if (attr && !strncmp(attr, csAttr, MAX_ATTRIBUTE - 1)) {
  165: 			val = strtok_r(NULL, "=\r\n", &a_brk);
  166: 			if (val && strlen(val)) {
  167: 				if (psVal)
  168: 					strlcpy(psVal, val, *pnLen);
  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
  185:  *
  186:  * @s = Session item
  187:  * @csAttr = Attribute for erasing
  188:  * return: 0 Ok, -1 error: in parameter
  189:  */
  190: int
  191: sess_DelValue(ait_sess_t * __restrict s, const char *csAttr)
  192: {
  193: 	register int i;
  194: 	int attrlen;
  195: 	char *Buffer, *Shared, szAttr[MAX_ATTRIBUTE];
  196: 	char *peer, *p_brk;
  197: 
  198: 	if (!s || !csAttr || !*csAttr)
  199: 		return -1;
  200: 	else
  201: 		attrlen = strlen(csAttr);
  202: 	Buffer = Shared = NULL;
  203: 	strlcpy(szAttr, csAttr, sizeof szAttr);
  204: 	strlcat(szAttr, "=", sizeof szAttr);
  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 {
  218: 		DEC_SEM(s);
  219: 		memcpy(Shared, s->addr, s->eom);
  220: 	}
  221: 
  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)) {
  224: 		if (!strncmp(peer, csAttr, attrlen))
  225: 			if (peer[attrlen] == '=' || peer[attrlen] == *MEM_DELIM || !peer[attrlen] ||
  226: 					peer[attrlen] == '\r' || peer[attrlen] == '\n')
  227: 				continue;
  228: 
  229: 		strlcat(Buffer, peer, s->eom);
  230: 		strlcat(Buffer, MEM_DELIM, s->eom);
  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: 
  238: 	INC_SEM(s);
  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
  246:  *
  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
  252:  */
  253: int
  254: sess_SetValue(ait_sess_t * __restrict s, const char *csAttr, const char *psVal)
  255: {
  256: 	register int i;
  257: 	int upd, def = IS_VAL;
  258: 	char *Buffer, *Shared, szAttr[MAX_ATTRIBUTE];
  259: 	char *peer, *p_brk;
  260: 
  261: 	if (!s || !csAttr || !*csAttr)
  262: 		return -1;
  263: 	else
  264: 		Buffer = Shared = NULL;
  265: 	strlcpy(szAttr, csAttr, sizeof szAttr);
  266: 	strlcat(szAttr, "=", sizeof szAttr);
  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 {
  280: 		DEC_SEM(s);
  281: 		memcpy(Shared, s->addr, s->eom);
  282: 	}
  283: 
  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)) {
  286: 		if (!strncmp(peer, szAttr, strlen(szAttr))) {
  287: 			upd++;
  288: 			if (psVal) {
  289: 				strlcat(Buffer, szAttr, s->eom);
  290: 				strlcat(Buffer, psVal, s->eom);
  291: 				strlcat(Buffer, MEM_DELIM, s->eom);
  292: 			} else {
  293: 				strlcat(Buffer, csAttr, s->eom);
  294: 				strlcat(Buffer, MEM_DELIM, s->eom);
  295: 				def = IS_DEF;
  296: 			}
  297: 			continue;
  298: 		}
  299: 
  300: 		strlcat(Buffer, peer, s->eom);
  301: 		strlcat(Buffer, MEM_DELIM, s->eom);
  302: 	}
  303: 
  304: 	if (!upd) {
  305: 		if (psVal) {
  306: 			strlcat(Buffer, szAttr, s->eom);
  307: 			strlcat(Buffer, psVal, s->eom);
  308: 			strlcat(Buffer, MEM_DELIM, s->eom);
  309: 		} else {
  310: 			strlcat(Buffer, csAttr, s->eom);
  311: 			strlcat(Buffer, MEM_DELIM, s->eom);
  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: 
  322: 	INC_SEM(s);
  323: 	free(Shared);
  324: 	free(Buffer);
  325: 	return upd | def;
  326: }
  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>