Annotation of libaitcfg/src/queue.c, revision 1.6
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.6 ! misho 6: * $Id: queue.c,v 1.5.2.1 2011/05/01 17:23:29 misho Exp $
1.2 misho 7: *
1.6 ! 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 "aitcfg.h"
48:
49:
50: /*
51: * SelectAttribute() Select item //{tagPair} from config list with attribute parameter(s)
52: * @cfg = Head list element
53: * @csSec = Config section //[{csSec}], if NULL search in *default* section
54: * @csAttr = Config attribute //{csAttr} = ..., if NULL search in *any* attribute
55: * return: NULL not found attribute; //{tagPair} selected first seen attribute item from list
56: */
57: static inline struct tagPair *SelectAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr)
58: {
59: struct tagPair *av;
60:
61: if (!cfg)
62: return NULL;
63:
64: for (av = cfg->slh_first; av; av = av->sle_next) {
65: if ((!csSec || !*csSec) && !av->psSection) {
66: if (!csAttr)
67: return av;
68: if (!strcmp((char*) av->psAttribute, (char*) csAttr))
69: return av;
70: }
71: if (csSec && av->psSection && !strcmp((char*) av->psSection, (char*) csSec)) {
72: if (!csAttr)
73: return av;
74: if (!strcmp((char*) av->psAttribute, (char*) csAttr))
75: return av;
76: }
77: }
78:
79: return NULL;
80: }
81:
82: /*
83: * DestroyAttribute() Free //{tagPair} item elements memory and destroy resource
84: * @pair = Free this element
85: */
86: static inline void DestroyAttribute(struct tagPair *pair)
87: {
88: if (!pair)
89: return;
90:
91: if (pair->psValue)
92: free(pair->psValue);
93: if (pair->psAttribute)
94: free(pair->psAttribute);
95: if (pair->psSection)
96: free(pair->psSection);
97:
98: free(pair);
99: }
100:
101: // ----------------------------------------------
102:
103: /*
104: * cfg_FindAttribute() Find attribute position in config list
105: * @cfg = Head list element
106: * @csSec = Config section //[{csSec}]
107: * @csAttr = Config attribute //{csAttr} = ...
108: * return: 0 not found item; -1 error: null parameters; >0 position in list
109: */
110: inline int cfg_FindAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr)
111: {
112: struct tagPair *av;
113: register int cx = 0;
114:
115: if (!cfg || !csAttr)
116: return -1;
117:
118: for (av = cfg->slh_first; av; av = av->sle_next) {
119: ++cx;
120: if ((!csSec || !*csSec) && !av->psSection)
121: if (!strcmp((char*) av->psAttribute, (char*) csAttr))
122: return cx;
123: if (csSec && av->psSection && !strcmp((char*) av->psSection, (char*) csSec))
124: if (!strcmp((char*) av->psAttribute, (char*) csAttr))
125: return cx;
126: }
127:
128: return 0;
129: }
130:
131: /*
132: * cfg_UnsetAttribute() Unset item from config list and free resources
133: * @cfg = Head list element
134: * @csSec = Config section //[{csSec}], if NULL unset in *default* section
135: * @csAttr = Config attribute //{csAttr} = ..., if NULL unset as *any* attribute
136: * return: 0 item not found, -1 error: null parameters; >0 position in list
137: */
138: int cfg_UnsetAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr)
139: {
140: struct tagPair *av, *curr;
141: register int cx = 0;
142:
143: if (!cfg || !csAttr)
144: return -1;
145:
146: av = SelectAttribute(cfg, csSec, csAttr);
147: if (!av)
148: return 0;
149:
150: // remove element
151: // remove element when is first!
152: if (cfg->slh_first == av) {
153: cfg->slh_first = cfg->slh_first->sle_next;
154:
155: DestroyAttribute(av);
156: return 1;
157: }
158: // remove element in other cases...
159: curr = cfg->slh_first;
160: while (curr->sle_next != av) {
161: ++cx;
162: curr = curr->sle_next;
163: }
164: curr->sle_next = curr->sle_next->sle_next;
165:
166: DestroyAttribute(av);
167: return cx;
168: }
169:
170: /*
171: * cfg_SetAttribute() Set item in config list or add new item if not exists
172: * @cfg = Head list element
173: * @csSec = Config section //[{csSec}], if NULL set in *default* section
174: * @csAttr = Config attribute //{csAttr} = ..., if NULL set as *any* attribute
175: * @csVal = Config value //... = {csVal} to setup
176: * return: 0 nothing changed, -1 error: not enough memory; 1 find and update item; 2 added new item
177: */
178: int cfg_SetAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr, const u_char *csVal)
179: {
180: struct tagPair *av, *section;
1.3 misho 181: int len;
1.1 misho 182:
183: if (!cfg || !csAttr)
184: return -1;
185:
186: av = SelectAttribute(cfg, csSec, csAttr);
187: if (!av) {
188: section = SelectAttribute(cfg, csSec, NULL);
189:
190: av = malloc(sizeof(struct tagPair));
191: if (!av) {
192: LOGERR;
193: return -1;
194: } else {
195: memset(av, 0, sizeof(struct tagPair));
196:
197: if (!section) {
198: // add new element
199: av->sle_next = cfg->slh_first;
200: cfg->slh_first = av;
201: } else {
202: // add new element in existing section
203: av->sle_next = section->sle_next;
204: section->sle_next = av;
205: }
206: }
207: // added section name to element
208: if (csSec && *csSec) {
1.3 misho 209: len = strlen((char*) csSec) + 1;
210: av->psSection = malloc(len);
1.1 misho 211: if (!av->psSection) {
212: LOGERR;
213: free(av);
214: return -1;
215: } else {
1.3 misho 216: strlcpy((char*) av->psSection, (char*) csSec, len);
1.1 misho 217: }
218: } else
219: av->psSection = NULL;
220:
221: // added attribute to element
1.3 misho 222: len = strlen((char*) csAttr) + 1;
223: av->psAttribute = malloc(len);
1.1 misho 224: if (!av->psAttribute) {
225: LOGERR;
226: free(av->psSection);
227: free(av);
228: return -1;
229: } else {
1.3 misho 230: strlcpy((char*) av->psAttribute, (char*) csAttr, len);
1.1 misho 231: }
232: // added value to element
233: if (csVal && *csVal) {
1.3 misho 234: len = strlen((char*) csVal) + 1;
235: av->psValue = malloc(len);
1.1 misho 236: if (!av->psValue) {
237: LOGERR;
238: free(av->psAttribute);
239: free(av->psSection);
240: free(av);
241: return -1;
242: } else {
1.3 misho 243: strlcpy((char*) av->psValue, (char*) csVal, len);
1.1 misho 244: }
245: } else {
246: av->psValue = malloc(1);
247: *av->psValue = 0;
248: }
249:
250: // Added new element
251: return 2;
252: }
253:
254: if (strcmp((char*) csVal, (char*) av->psValue)) {
1.3 misho 255: len = strlen((char*) csVal) + 1;
256: av->psValue = realloc(av->psValue, len);
257: strlcpy((char*) av->psValue, (char*) csVal, len);
1.1 misho 258:
259: // Update element
260: return 1;
261: }
262:
263: // Nothing happens ... finded & values is equal!
264: return 0;
265: }
266:
267: /*
268: * cfg_GetAttribute() Get item from config list and return his value
269: * @cfg = Head list element
270: * @csSec = Config section //[{csSec}], if NULL unset in *default* section
271: * @csAttr = Config attribute //{csAttr} = ..., if NULL unset as *any* attribute
272: * return: NULL item not found or null parameters; !=NULL value const string
273: */
274: inline const u_char *cfg_GetAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr)
275: {
276: struct tagPair *av;
277:
278: if (!cfg || !csAttr)
279: return NULL;
280:
281: av = SelectAttribute(cfg, csSec, csAttr);
282: if (!av)
283: return NULL;
284:
285: return av->psValue;
286: }
287:
1.4 misho 288: /*
289: * cfg_FirstItem() Get first item from config list and return his value
290: * @cfg = Head list element
291: * return: NULL if no items in list; !=NULL first pair item
292: */
293: inline struct tagPair *cfg_FirstItem(sl_config * __restrict cfg)
294: {
295: return cfg->slh_first;
296: }
297:
1.1 misho 298: // --------------------------------------------------------------
299:
300: /*
301: * cfg_LoadAttribute() Extended get attribute, if not found item return *default value*
302: * @cfg = Head list element
303: * @csSec = Config section //[{csSec}], if NULL unset in *default* section
304: * @csAttr = Config attribute //{csAttr} = ..., if NULL unset as *any* attribute
305: * @psVal = Return buffer for item Value //... = {psVal}
306: * @ValLen = Length of buffer //{psVal} for return
307: * @csDefValue = *Default Value* for return in //{psVal}, if not found item in config list
308: * return: 0 item not found, -1 error: null parameters; >0 number of copied bytes in //{psVal}
309: */
310: int cfg_LoadAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr,
311: u_char * __restrict psVal, int ValLen, const char *csDefValue)
312: {
313: struct tagPair *av;
314: int ret = 0;
315:
316: if (!cfg || !csAttr || !ValLen || !psVal)
317: return -1;
318:
319: av = SelectAttribute(cfg, csSec, csAttr);
320: if (!av) {
321: if (csDefValue) {
1.2 misho 322: strlcpy((char*) psVal, csDefValue, ValLen);
1.1 misho 323: ret = strlen((char*) psVal);
324: }
325:
326: return ret;
327: }
328:
329: if (!av->psValue || !*av->psValue) {
330: if (csDefValue) {
1.2 misho 331: strlcpy((char*) psVal, csDefValue, ValLen);
1.1 misho 332: ret = strlen((char*) psVal);
333: }
334: } else {
1.2 misho 335: strlcpy((char*) psVal, (char*) av->psValue, ValLen);
1.1 misho 336: ret = strlen((char*) psVal);
337: }
338:
339: return ret;
340: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>