/*************************************************************************
* (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>