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: parse.c,v 1.2.2.1 2009/09/09 09:29:37 misho Exp $
7: *
8: *************************************************************************/
9: #include "global.h"
10: #include "aitcfg.h"
11: #include "tools.h"
12:
13:
14: // cfgDbg() Debug/Log operation
15: static inline int cfgDbg(FILE *f, char *fmt, ...)
16: {
17: int ret = 0;
18: va_list lst;
19:
20: va_start(lst, fmt);
21: ret = vfprintf(f, fmt, lst);
22: va_end(lst);
23:
24: return ret;
25: }
26:
27: // cfgWrite() Write to file from config list
28: static inline int cfgWrite(FILE *f, sl_config * __restrict cfg, int whitespace)
29: {
30: struct tagPair *av;
31: time_t tim;
32: char szTime[MAX_STR + 1];
33: u_char szSection[MAX_STR + 1];
34:
35: bzero(szSection, MAX_STR + 1);
36:
37: bzero(szTime, MAX_STR + 1);
38: time(&tim);
39: strftime(szTime, MAX_STR, "(UTC) %Y-%m-%d %H:%M:%S", gmtime(&tim));
40: if (!cfgDbg(f, "## Write Config :: %s\n#\n", szTime)) {
41: LOGERR;
42: return -1;
43: }
44:
45: for (av = cfg->slh_first; av; av = av->sle_next) {
46: if (av->psSection && strcmp((char*) av->psSection, (char*) szSection)) {
47: strlcpy((char*) szSection, (char*) av->psSection, MAX_STR + 1);
48: if (!cfgDbg(f, "\n[%s]\n", av->psSection)) {
49: LOGERR;
50: return -1;
51: }
52: }
53: if (!av->psSection && *szSection) {
54: bzero(szSection, MAX_STR + 1);
55: if (!cfgDbg(f, "\n[]\n")) {
56: LOGERR;
57: return -1;
58: }
59: }
60:
61: if (whitespace) {
62: if (!cfgDbg(f, "%s = %s\n", av->psAttribute, av->psValue)) {
63: LOGERR;
64: return -1;
65: }
66: } else {
67: if (!cfgDbg(f, "%s=%s\n", av->psAttribute, av->psValue)) {
68: LOGERR;
69: return -1;
70: }
71: }
72: }
73:
74: bzero(szTime, MAX_STR + 1);
75: time(&tim);
76: strftime(szTime, MAX_STR, "(UTC) %Y-%m-%d %H:%M:%S", gmtime(&tim));
77: if (!cfgDbg(f, "\n#\n## Done. :: %s\n", szTime)) {
78: LOGERR;
79: return -1;
80: }
81:
82: return 0;
83: }
84:
85: // -----------------------------------------
86:
87: /*
88: * ReadConfig() Read from file and add new item to config list
89: * @f = file resource
90: * @cfg = Head list element
91: * return: 0 ok; -1 error:: can`t allocate memory
92: */
93: int ReadConfig(FILE *f, sl_config * __restrict cfg)
94: {
95: u_char szLine[MAX_STR + 1];
96: u_char szSection[MAX_STR + 1], *psAttr, *psVal;
97: int pos;
98: struct tagPair *av;
99:
100: memset(szSection, 0, MAX_STR + 1);
101: while (!feof(f)) {
102: memset(szLine, 0, MAX_STR + 1);
103: fgets((char*) szLine, MAX_STR, f);
104: trim(szLine);
105: #ifdef __DEBUG
106: cfgDbg(stdout, "DEBUG:: RAW |%s|\n", szLine);
107: #endif
108:
109: // End of config
110: if (*szLine == '.')
111: break;
112: // Comment
113: if (*szLine == '#' || *szLine == ';' || !*szLine)
114: continue;
115:
116: #ifdef __DEBUG
117: cfgDbg(stdout, "DEBUG:: Clean |%s|\n", szLine);
118: #endif
119:
120: // Section
121: if (*szLine == '[') {
122: pos = strlen((char*) szLine) - 1;
123: if (szLine[pos] != ']') {
124: #ifdef __DEBUG
125: cfgDbg(stdout, "WARNING:: Ignore section %s ... not closed breket\n", szLine);
126: #endif
127: } else {
128: szLine[pos] = 0;
129: strncpy((char*) szSection, (char*) szLine + 1, MAX_STR);
130: #ifdef __DEBUG
131: cfgDbg(stdout, "DEBUG:: Section %s\n", szSection);
132: #endif
133: }
134: continue;
135: }
136:
137: // Devide pairs
138: pos = strchr((char*) szLine, '=') ? strchr((char*) szLine, '=') - (char*) szLine : 0;
139: if (!pos) {
140: #ifdef __DEBUG
141: cfgDbg(stdout, "WARNING:: Ignore a/v %s ... format error!\n", szLine);
142: #endif
143: continue;
144: } else {
145: av = malloc(sizeof(struct tagPair));
146: if (!av) {
147: LOGERR;
148: return -1;
149: } else {
150: memset(av, 0, sizeof(struct tagPair));
151: // added new element
152: av->sle_next = cfg->slh_first;
153: cfg->slh_first = av;
154: }
155: // added section name to element
156: if (*szSection) {
157: av->psSection = malloc(strlen((char*) szSection) + 1);
158: if (!av->psSection) {
159: LOGERR;
160: free(av);
161: return -1;
162: } else
163: strlcpy((char*) av->psSection, (char*) szSection, strlen((char*) szSection) + 1);
164: } else
165: av->psSection = NULL;
166:
167: psAttr = szLine;
168: psVal = (szLine + pos + 1);
169: szLine[pos] = 0;
170: rtrim(psAttr);
171: ltrim(psVal);
172: #ifdef __DEBUG
173: cfgDbg(stdout, "DEBUG:: Attr(%p) ->%s size=%d Value(%p) ->%s size=%d\n",
174: psAttr, psAttr, strlen((char*) psAttr), psVal, psVal, strlen((char*) psVal));
175: #endif
176: // added attribute to element
177: av->psAttribute = malloc(strlen((char*) psAttr) + 1);
178: if (!av->psAttribute) {
179: LOGERR;
180: free(av->psSection);
181: free(av);
182: return -1;
183: } else
184: strlcpy((char*) av->psAttribute, (char*) psAttr, strlen((char*) psAttr) + 1);
185: // added value to element
186: av->psValue = malloc(strlen((char*) psVal) + 1);
187: if (!av->psValue) {
188: LOGERR;
189: free(av->psAttribute);
190: free(av->psSection);
191: free(av);
192: return -1;
193: } else
194: strlcpy((char*) av->psValue, (char*) psVal, strlen((char*) psVal) + 1);
195: }
196: }
197:
198: return 0;
199: }
200:
201: /*
202: * WriteConfig() Write to file from items in config list
203: * @f = file resource
204: * @cfg = Head list element
205: * return: 0 ok; -1 error:: can`t write to file
206: */
207: int WriteConfig(FILE *f, sl_config * __restrict cfg)
208: {
209: return cfgWrite(f, cfg, 1);
210: }
211:
212: /*
213: * cfg_WriteConfig() Write to file from items in config list without whitespaces!
214: * @f = file resource
215: * @cfg = Head list element
216: * return: 0 ok; -1 error:: can`t write to file
217: */
218: int cfg_WriteConfig(FILE *f, sl_config * __restrict cfg)
219: {
220: return cfgWrite(f, cfg, 0);
221: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>