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.2 2009/09/09 09:07:31 misho Exp $
7: *
8: *************************************************************************/
9: #include "global.h"
10: #include "aitcfg.h"
11:
12:
13: /*
14: * SelectAttribute() Select item //{tagPair} from config list with attribute parameter(s)
15: * @cfg = Head list element
16: * @csSec = Config section //[{csSec}], if NULL search in *default* section
17: * @csAttr = Config attribute //{csAttr} = ..., if NULL search in *any* attribute
18: * return: NULL not found attribute; //{tagPair} selected first seen attribute item from list
19: */
20: static inline struct tagPair *SelectAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr)
21: {
22: struct tagPair *av;
23:
24: if (!cfg)
25: return NULL;
26:
27: for (av = cfg->slh_first; av; av = av->sle_next) {
28: if ((!csSec || !*csSec) && !av->psSection) {
29: if (!csAttr)
30: return av;
31: if (!strcmp((char*) av->psAttribute, (char*) csAttr))
32: return av;
33: }
34: if (csSec && av->psSection && !strcmp((char*) av->psSection, (char*) csSec)) {
35: if (!csAttr)
36: return av;
37: if (!strcmp((char*) av->psAttribute, (char*) csAttr))
38: return av;
39: }
40: }
41:
42: return NULL;
43: }
44:
45: /*
46: * DestroyAttribute() Free //{tagPair} item elements memory and destroy resource
47: * @pair = Free this element
48: */
49: static inline void DestroyAttribute(struct tagPair *pair)
50: {
51: if (!pair)
52: return;
53:
54: if (pair->psValue)
55: free(pair->psValue);
56: if (pair->psAttribute)
57: free(pair->psAttribute);
58: if (pair->psSection)
59: free(pair->psSection);
60:
61: free(pair);
62: }
63:
64: // ----------------------------------------------
65:
66: /*
67: * cfg_FindAttribute() Find attribute position in config list
68: * @cfg = Head list element
69: * @csSec = Config section //[{csSec}]
70: * @csAttr = Config attribute //{csAttr} = ...
71: * return: 0 not found item; -1 error: null parameters; >0 position in list
72: */
73: inline int cfg_FindAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr)
74: {
75: struct tagPair *av;
76: register int cx = 0;
77:
78: if (!cfg || !csAttr)
79: return -1;
80:
81: for (av = cfg->slh_first; av; av = av->sle_next) {
82: ++cx;
83: if ((!csSec || !*csSec) && !av->psSection)
84: if (!strcmp((char*) av->psAttribute, (char*) csAttr))
85: return cx;
86: if (csSec && av->psSection && !strcmp((char*) av->psSection, (char*) csSec))
87: if (!strcmp((char*) av->psAttribute, (char*) csAttr))
88: return cx;
89: }
90:
91: return 0;
92: }
93:
94: /*
95: * cfg_UnsetAttribute() Unset item from config list and free resources
96: * @cfg = Head list element
97: * @csSec = Config section //[{csSec}], if NULL unset in *default* section
98: * @csAttr = Config attribute //{csAttr} = ..., if NULL unset as *any* attribute
99: * return: 0 item not found, -1 error: null parameters; >0 position in list
100: */
101: int cfg_UnsetAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr)
102: {
103: struct tagPair *av, *curr;
104: register int cx = 0;
105:
106: if (!cfg || !csAttr)
107: return -1;
108:
109: av = SelectAttribute(cfg, csSec, csAttr);
110: if (!av)
111: return 0;
112:
113: // remove element
114: // remove element when is first!
115: if (cfg->slh_first == av) {
116: cfg->slh_first = cfg->slh_first->sle_next;
117:
118: DestroyAttribute(av);
119: return 1;
120: }
121: // remove element in other cases...
122: curr = cfg->slh_first;
123: while (curr->sle_next != av) {
124: ++cx;
125: curr = curr->sle_next;
126: }
127: curr->sle_next = curr->sle_next->sle_next;
128:
129: DestroyAttribute(av);
130: return cx;
131: }
132:
133: /*
134: * cfg_SetAttribute() Set item in config list or add new item if not exists
135: * @cfg = Head list element
136: * @csSec = Config section //[{csSec}], if NULL set in *default* section
137: * @csAttr = Config attribute //{csAttr} = ..., if NULL set as *any* attribute
138: * @csVal = Config value //... = {csVal} to setup
139: * return: 0 nothing changed, -1 error: not enough memory; 1 find and update item; 2 added new item
140: */
141: int cfg_SetAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr, const u_char *csVal)
142: {
143: struct tagPair *av, *section;
144:
145: if (!cfg || !csAttr)
146: return -1;
147:
148: av = SelectAttribute(cfg, csSec, csAttr);
149: if (!av) {
150: section = SelectAttribute(cfg, csSec, NULL);
151:
152: av = malloc(sizeof(struct tagPair));
153: if (!av) {
154: LOGERR;
155: return -1;
156: } else {
157: memset(av, 0, sizeof(struct tagPair));
158:
159: if (!section) {
160: // add new element
161: av->sle_next = cfg->slh_first;
162: cfg->slh_first = av;
163: } else {
164: // add new element in existing section
165: av->sle_next = section->sle_next;
166: section->sle_next = av;
167: }
168: }
169: // added section name to element
170: if (csSec && *csSec) {
171: av->psSection = malloc(strlen((char*) csSec) + 1);
172: if (!av->psSection) {
173: LOGERR;
174: free(av);
175: return -1;
176: } else {
177: strlcpy((char*) av->psSection, (char*) csSec, strlen((char*) csSec) + 1);
178: }
179: } else
180: av->psSection = NULL;
181:
182: // added attribute to element
183: av->psAttribute = malloc(strlen((char*) csAttr) + 1);
184: if (!av->psAttribute) {
185: LOGERR;
186: free(av->psSection);
187: free(av);
188: return -1;
189: } else {
190: strlcpy((char*) av->psAttribute, (char*) csAttr, strlen((char*) csAttr) + 1);
191: }
192: // added value to element
193: if (csVal && *csVal) {
194: av->psValue = malloc(strlen((char*) csVal) + 1);
195: if (!av->psValue) {
196: LOGERR;
197: free(av->psAttribute);
198: free(av->psSection);
199: free(av);
200: return -1;
201: } else {
202: strlcpy((char*) av->psValue, (char*) csVal, strlen((char*) csVal) + 1);
203: }
204: } else {
205: av->psValue = malloc(1);
206: *av->psValue = 0;
207: }
208:
209: // Added new element
210: return 2;
211: }
212:
213: if (strcmp((char*) csVal, (char*) av->psValue)) {
214: av->psValue = realloc(av->psValue, strlen((char*) csVal) + 1);
215: strlcpy((char*) av->psValue, (char*) csVal, strlen((char*) csVal) + 1);
216:
217: // Update element
218: return 1;
219: }
220:
221: // Nothing happens ... finded & values is equal!
222: return 0;
223: }
224:
225: /*
226: * cfg_GetAttribute() Get item from config list and return his value
227: * @cfg = Head list element
228: * @csSec = Config section //[{csSec}], if NULL unset in *default* section
229: * @csAttr = Config attribute //{csAttr} = ..., if NULL unset as *any* attribute
230: * return: NULL item not found or null parameters; !=NULL value const string
231: */
232: inline const u_char *cfg_GetAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr)
233: {
234: struct tagPair *av;
235:
236: if (!cfg || !csAttr)
237: return NULL;
238:
239: av = SelectAttribute(cfg, csSec, csAttr);
240: if (!av)
241: return NULL;
242:
243: return av->psValue;
244: }
245:
246: // --------------------------------------------------------------
247:
248: /*
249: * cfg_LoadAttribute() Extended get attribute, if not found item return *default value*
250: * @cfg = Head list element
251: * @csSec = Config section //[{csSec}], if NULL unset in *default* section
252: * @csAttr = Config attribute //{csAttr} = ..., if NULL unset as *any* attribute
253: * @psVal = Return buffer for item Value //... = {psVal}
254: * @ValLen = Length of buffer //{psVal} for return
255: * @csDefValue = *Default Value* for return in //{psVal}, if not found item in config list
256: * return: 0 item not found, -1 error: null parameters; >0 number of copied bytes in //{psVal}
257: */
258: int cfg_LoadAttribute(sl_config * __restrict cfg, const u_char *csSec, const u_char *csAttr,
259: u_char * __restrict psVal, int ValLen, const char *csDefValue)
260: {
261: struct tagPair *av;
262: int ret = 0;
263:
264: if (!cfg || !csAttr || !ValLen || !psVal)
265: return -1;
266:
267: av = SelectAttribute(cfg, csSec, csAttr);
268: if (!av) {
269: if (csDefValue) {
270: strlcpy((char*) psVal, csDefValue, ValLen);
271: ret = strlen((char*) psVal);
272: }
273:
274: return ret;
275: }
276:
277: if (!av->psValue || !*av->psValue) {
278: if (csDefValue) {
279: strlcpy((char*) psVal, csDefValue, ValLen);
280: ret = strlen((char*) psVal);
281: }
282: } else {
283: strlcpy((char*) psVal, (char*) av->psValue, ValLen);
284: ret = strlen((char*) psVal);
285: }
286:
287: return ret;
288: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>