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