File:  [ELWIX - Embedded LightWeight unIX -] / libaitsess / src / sess.c
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Sat Apr 30 21:35:21 2011 UTC (13 years, 1 month ago) by misho
Branches: MAIN
CVS tags: sess2_1, SESS2_0, HEAD
VER 2.0

/*************************************************************************
* (C) 2008 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
*  by Michael Pounov <misho@openbsd-bg.org>
*
* $Author: misho $
* $Id: sess.c,v 1.2 2011/04/30 21:35:21 misho Exp $
*
*************************************************************************/
#include "global.h"
#include "aitsess.h"


/*
 * sess_FreeValues() Free all values from value array allocated from sess_GetValues()
 * @ppsVals = Array strings
 * return: none
*/
inline void sess_FreeValues(char *** __restrict ppsVals)
{
	char **ptr;

	for (ptr = *ppsVals; *ptr; ptr++)
		free(*ptr);
	free(*ppsVals);
	*ppsVals = NULL;
}

/*
 * sess_GetValues() Get all values from session shared memory
 * @s = Session item
 * @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)
{
	register int i;
	char **valz, *Shared = NULL;
	char *peer, *p_brk;

	if (!s || !ppsVals)
		return -1;
	valz = malloc(sizeof(caddr_t));
	if (!valz) {
		LOGERR;
		return -1;
	} else
		*valz = NULL;

	// allocated memory & mirrored shared memory into this
	Shared = malloc(s->eom);
	if (!Shared) {
		LOGERR;
		free(valz);
		return -1;
	} else
		memcpy(Shared, s->addr, s->eom);

	for (i = 0, peer = strtok_r(Shared, MEM_DELIM"\r\n", &p_brk); peer; 
			peer = strtok_r(NULL, MEM_DELIM"\r\n", &p_brk)) {
		if (!strchr(peer, '='))
			continue;
		else
			i++;

		valz = realloc(valz, (i + 1) * sizeof(caddr_t));
		if (!valz) {
			LOGERR;
			free(Shared);
			return -1;
		} else
			valz[i] = NULL;

		valz[i - 1] = strdup(peer);
	}

	free(Shared);
	*ppsVals = valz;
	return i;
}

/*
 * sess_GetValue() Get value from session shared memory from attribute
 * @s = Session item
 * @csAttr = Attribute for search
 * @psVal = Return string buffer
 * @pnLen = Length of return string buffer, 
	// *{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)
{
	register int i;
	int def = IS_VAL;
	char *Shared = NULL;
	char *peer, *p_brk, *a_brk, *attr, *val;

	if (!s || !csAttr || !*csAttr)
		return -1;
	if (psVal) {
		if (pnLen && *pnLen > 0)
			memset(psVal, 0, *pnLen);
		else
			return -1;
	}

	// allocated memory & mirrored shared memory into this
	Shared = malloc(s->eom);
	if (!Shared) {
		LOGERR;
		return -1;
	} else
		memcpy(Shared, s->addr, s->eom);

	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)) {
			val = strtok_r(NULL, "=\r\n", &a_brk);
			if (val && strlen(val)) {
				if (psVal)
					strlcpy(psVal, val, *pnLen);
				if (pnLen)
					*pnLen = strlen(val);
			} else
				def = IS_DEF;

			free(Shared);
			return i | def;
		}
	}

	free(Shared);
	return 0;
}

/*
 * sess_DelValue() Delete item from session shared memory
 * @s = Session item
 * @csAttr = Attribute for erasing
 * return: 0 Ok, -1 error: in parameter
*/
int sess_DelValue(tagSess * __restrict s, const char *csAttr)
{
	register int i;
	int ret, attrlen;
	char *Buffer, *Shared, szAttr[MAX_ATTRIBUTE + 1];
	char *peer, *p_brk;

	if (!s || !csAttr || !*csAttr)
		return -1;
	else
		attrlen = strlen(csAttr);
	Buffer = Shared = NULL;
	memset(szAttr, 0, MAX_ATTRIBUTE + 1);
	strncpy(szAttr, csAttr, MAX_ATTRIBUTE - 1);
	strcat(szAttr, "=");

	Buffer = malloc(s->eom);
	if (!Buffer) {
		LOGERR;
		return -1;
	} else
		memset(Buffer, 0, s->eom);
	Shared = malloc(s->eom);
	if (!Shared) {
		LOGERR;
		free(Buffer);
		return -1;
	} else {
		DEC_SEMAPHORE(s, ret);
		memcpy(Shared, s->addr, s->eom);
	}

	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)) {
		if (!strncmp(peer, csAttr, attrlen))
			if (peer[attrlen] == '=' || peer[attrlen] == *MEM_DELIM || !peer[attrlen] ||
					peer[attrlen] == '\r' || peer[attrlen] == '\n')
				continue;

		strcat(Buffer, peer);
		strcat(Buffer, MEM_DELIM);
	}

	memset(s->addr, 0, s->eom);
	memcpy(s->addr, Buffer, s->eom);

	if (s->type == SHARED_MAP)
		msync(s->addr, 0, MS_SYNC | MS_INVALIDATE);

	ADD_SEMAPHORE(s, ret);
	free(Shared);
	free(Buffer);
	return 0;
}

/*
 * sess_SetValue() Set item into session shared memory or update if find it
 * @s = Session item
 * @csAttr = Attribute
 * @psVal = Value
 * 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)
{
	register int i;
	int upd, ret, def = IS_VAL;
	char *Buffer, *Shared, szAttr[MAX_ATTRIBUTE + 1];
	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, "=");

	Buffer = malloc(s->eom);
	if (!Buffer) {
		LOGERR;
		return -1;
	} else
		memset(Buffer, 0, s->eom);
	Shared = malloc(s->eom);
	if (!Shared) {
		LOGERR;
		free(Buffer);
		return -1;
	} else {
		DEC_SEMAPHORE(s, ret);
		memcpy(Shared, s->addr, s->eom);
	}

	for (i = 1, upd = 0, peer = strtok_r(Shared, MEM_DELIM"\r\n", &p_brk); peer; 
			i++, peer = strtok_r(NULL, MEM_DELIM"\r\n", &p_brk)) {
		if (!strncmp(peer, szAttr, strlen(szAttr))) {
			upd++;
			if (psVal) {
				strcat(Buffer, szAttr);
				strcat(Buffer, psVal);
				strcat(Buffer, MEM_DELIM);
			} else {
				strcat(Buffer, csAttr);
				strcat(Buffer, MEM_DELIM);
				def = IS_DEF;
			}
			continue;
		}

		strcat(Buffer, peer);
		strcat(Buffer, MEM_DELIM);
	}

	if (!upd) {
		if (psVal) {
			strcat(Buffer, szAttr);
			strcat(Buffer, psVal);
			strcat(Buffer, MEM_DELIM);
		} else {
			strcat(Buffer, csAttr);
			strcat(Buffer, MEM_DELIM);
			def = IS_DEF;
		}
		def |= IS_ADD;
	}

	memset(s->addr, 0, s->eom);
	memcpy(s->addr, Buffer, s->eom);

	if (s->type == SHARED_MAP)
		msync(s->addr, 0, MS_SYNC | MS_INVALIDATE);

	ADD_SEMAPHORE(s, ret);
	free(Shared);
	free(Buffer);
	return upd | def;
}

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