Annotation of libaitsess/src/sess.c, revision 1.4.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.4.4.1 ! misho 6: * $Id: sess.c,v 1.4 2012/02/10 23:38:30 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:
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: */
1.1 misho 46: #include "global.h"
47: #include "aitsess.h"
48:
49:
50: /*
1.2 misho 51: * sess_FreeValues() Free all values from value array allocated from sess_GetValues()
1.4 misho 52: *
1.2 misho 53: * @ppsVals = Array strings
54: * return: none
1.4 misho 55: */
1.3 misho 56: inline void
57: sess_FreeValues(char *** __restrict ppsVals)
1.2 misho 58: {
59: char **ptr;
60:
1.3 misho 61: assert(ppsVals);
62: if (!ppsVals)
63: return;
64:
1.2 misho 65: for (ptr = *ppsVals; *ptr; ptr++)
1.4.4.1 ! misho 66: io_free(*ptr);
! 67: io_free(*ppsVals);
1.2 misho 68: *ppsVals = NULL;
69: }
70:
71: /*
72: * sess_GetValues() Get all values from session shared memory
1.4 misho 73: *
1.2 misho 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!)
1.4 misho 77: */
1.3 misho 78: int
1.4 misho 79: sess_GetValues(ait_sess_t * __restrict s, char ***ppsVals)
1.2 misho 80: {
81: register int i;
82: char **valz, *Shared = NULL;
83: char *peer, *p_brk;
84:
85: if (!s || !ppsVals)
86: return -1;
1.4.4.1 ! misho 87: valz = io_malloc(sizeof(caddr_t));
1.2 misho 88: if (!valz) {
89: LOGERR;
90: return -1;
91: } else
92: *valz = NULL;
93:
94: // allocated memory & mirrored shared memory into this
1.4.4.1 ! misho 95: Shared = io_malloc(s->eom);
1.2 misho 96: if (!Shared) {
97: LOGERR;
1.4.4.1 ! misho 98: io_free(valz);
1.2 misho 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:
1.4.4.1 ! misho 110: valz = io_realloc(valz, (i + 1) * sizeof(caddr_t));
1.2 misho 111: if (!valz) {
112: LOGERR;
1.4.4.1 ! misho 113: io_free(Shared);
1.2 misho 114: return -1;
115: } else
116: valz[i] = NULL;
117:
1.4.4.1 ! misho 118: valz[i - 1] = io_strdup(peer);
1.2 misho 119: }
120:
1.4.4.1 ! misho 121: io_free(Shared);
1.2 misho 122: *ppsVals = valz;
123: return i;
124: }
125:
126: /*
1.1 misho 127: * sess_GetValue() Get value from session shared memory from attribute
1.4 misho 128: *
1.1 misho 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
1.4 misho 135: */
1.3 misho 136: int
1.4 misho 137: sess_GetValue(ait_sess_t * __restrict s, const char *csAttr, char *psVal, int *pnLen)
1.1 misho 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
1.4.4.1 ! misho 154: Shared = io_malloc(s->eom);
1.1 misho 155: if (!Shared) {
156: LOGERR;
157: return -1;
158: } else
159: memcpy(Shared, s->addr, s->eom);
160:
1.2 misho 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)) {
1.1 misho 163: attr = strtok_r(peer, "=\r\n", &a_brk);
1.4 misho 164: if (attr && !strncmp(attr, csAttr, MAX_ATTRIBUTE - 1)) {
1.1 misho 165: val = strtok_r(NULL, "=\r\n", &a_brk);
166: if (val && strlen(val)) {
167: if (psVal)
1.2 misho 168: strlcpy(psVal, val, *pnLen);
1.1 misho 169: if (pnLen)
170: *pnLen = strlen(val);
171: } else
172: def = IS_DEF;
173:
1.4.4.1 ! misho 174: io_free(Shared);
1.1 misho 175: return i | def;
176: }
177: }
178:
1.4.4.1 ! misho 179: io_free(Shared);
1.1 misho 180: return 0;
181: }
182:
183: /*
184: * sess_DelValue() Delete item from session shared memory
1.4 misho 185: *
1.1 misho 186: * @s = Session item
187: * @csAttr = Attribute for erasing
188: * return: 0 Ok, -1 error: in parameter
1.4 misho 189: */
1.3 misho 190: int
1.4 misho 191: sess_DelValue(ait_sess_t * __restrict s, const char *csAttr)
1.1 misho 192: {
193: register int i;
1.4 misho 194: int attrlen;
195: char *Buffer, *Shared, szAttr[MAX_ATTRIBUTE];
1.1 misho 196: char *peer, *p_brk;
197:
198: if (!s || !csAttr || !*csAttr)
199: return -1;
200: else
201: attrlen = strlen(csAttr);
202: Buffer = Shared = NULL;
1.4 misho 203: strlcpy(szAttr, csAttr, sizeof szAttr);
204: strlcat(szAttr, "=", sizeof szAttr);
1.1 misho 205:
1.4.4.1 ! misho 206: Buffer = io_malloc(s->eom);
1.1 misho 207: if (!Buffer) {
208: LOGERR;
209: return -1;
210: } else
211: memset(Buffer, 0, s->eom);
1.4.4.1 ! misho 212: Shared = io_malloc(s->eom);
1.1 misho 213: if (!Shared) {
214: LOGERR;
1.4.4.1 ! misho 215: io_free(Buffer);
1.1 misho 216: return -1;
217: } else {
1.4 misho 218: DEC_SEM(s);
1.1 misho 219: memcpy(Shared, s->addr, s->eom);
220: }
221:
1.2 misho 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)) {
1.1 misho 224: if (!strncmp(peer, csAttr, attrlen))
1.2 misho 225: if (peer[attrlen] == '=' || peer[attrlen] == *MEM_DELIM || !peer[attrlen] ||
1.1 misho 226: peer[attrlen] == '\r' || peer[attrlen] == '\n')
227: continue;
228:
1.4 misho 229: strlcat(Buffer, peer, s->eom);
230: strlcat(Buffer, MEM_DELIM, s->eom);
1.1 misho 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:
1.4 misho 238: INC_SEM(s);
1.4.4.1 ! misho 239: io_free(Shared);
! 240: io_free(Buffer);
1.1 misho 241: return 0;
242: }
243:
244: /*
245: * sess_SetValue() Set item into session shared memory or update if find it
1.4 misho 246: *
1.1 misho 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
1.4 misho 252: */
1.3 misho 253: int
1.4 misho 254: sess_SetValue(ait_sess_t * __restrict s, const char *csAttr, const char *psVal)
1.1 misho 255: {
256: register int i;
1.4 misho 257: int upd, def = IS_VAL;
258: char *Buffer, *Shared, szAttr[MAX_ATTRIBUTE];
1.1 misho 259: char *peer, *p_brk;
260:
261: if (!s || !csAttr || !*csAttr)
262: return -1;
263: else
264: Buffer = Shared = NULL;
1.4 misho 265: strlcpy(szAttr, csAttr, sizeof szAttr);
266: strlcat(szAttr, "=", sizeof szAttr);
1.1 misho 267:
1.4.4.1 ! misho 268: Buffer = io_malloc(s->eom);
1.1 misho 269: if (!Buffer) {
270: LOGERR;
271: return -1;
272: } else
273: memset(Buffer, 0, s->eom);
1.4.4.1 ! misho 274: Shared = io_malloc(s->eom);
1.1 misho 275: if (!Shared) {
276: LOGERR;
1.4.4.1 ! misho 277: io_free(Buffer);
1.1 misho 278: return -1;
279: } else {
1.4 misho 280: DEC_SEM(s);
1.1 misho 281: memcpy(Shared, s->addr, s->eom);
282: }
283:
1.2 misho 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)) {
1.1 misho 286: if (!strncmp(peer, szAttr, strlen(szAttr))) {
287: upd++;
288: if (psVal) {
1.4 misho 289: strlcat(Buffer, szAttr, s->eom);
290: strlcat(Buffer, psVal, s->eom);
291: strlcat(Buffer, MEM_DELIM, s->eom);
1.1 misho 292: } else {
1.4 misho 293: strlcat(Buffer, csAttr, s->eom);
294: strlcat(Buffer, MEM_DELIM, s->eom);
1.1 misho 295: def = IS_DEF;
296: }
297: continue;
298: }
299:
1.4 misho 300: strlcat(Buffer, peer, s->eom);
301: strlcat(Buffer, MEM_DELIM, s->eom);
1.1 misho 302: }
303:
304: if (!upd) {
305: if (psVal) {
1.4 misho 306: strlcat(Buffer, szAttr, s->eom);
307: strlcat(Buffer, psVal, s->eom);
308: strlcat(Buffer, MEM_DELIM, s->eom);
1.1 misho 309: } else {
1.4 misho 310: strlcat(Buffer, csAttr, s->eom);
311: strlcat(Buffer, MEM_DELIM, s->eom);
1.1 misho 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:
1.4 misho 322: INC_SEM(s);
1.4.4.1 ! misho 323: io_free(Shared);
! 324: io_free(Buffer);
1.1 misho 325: return upd | def;
326: }
1.4 misho 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>