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