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