-rw-r--r-- | gammu/emb/common/misc/cfg.c | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/gammu/emb/common/misc/cfg.c b/gammu/emb/common/misc/cfg.c new file mode 100644 index 0000000..1c74874 --- a/dev/null +++ b/gammu/emb/common/misc/cfg.c | |||
@@ -0,0 +1,332 @@ | |||
1 | /* (c) 2002-2004 by Marcin Wiacek */ | ||
2 | |||
3 | #include <stdio.h> | ||
4 | #include <stdlib.h> | ||
5 | #include <string.h> | ||
6 | #include <ctype.h> | ||
7 | #include <errno.h> | ||
8 | #ifndef __OpenBSD__ | ||
9 | # include <wchar.h> | ||
10 | # include <wctype.h> | ||
11 | #endif | ||
12 | |||
13 | #include "../config.h" | ||
14 | #include "coding/coding.h" | ||
15 | #include "cfg.h" | ||
16 | #include "misc.h" | ||
17 | |||
18 | /* | ||
19 | * Read information from file in Windows INI format style | ||
20 | */ | ||
21 | INI_Section *INI_ReadFile(char *FileName, bool Unicode) | ||
22 | { | ||
23 | FILE *f; | ||
24 | bool FFEEUnicode=false; | ||
25 | int level = -1, buffer1used, buffer2used; | ||
26 | int bufferused, i, buffused=1000,buffread=1000, num; | ||
27 | unsigned charch[3], *buffer = NULL; | ||
28 | unsigned char*buffer2 = NULL, *buffer1 = NULL, buff[1000]; | ||
29 | INI_Section *INI_info = NULL, *INI_head = NULL, *heading; | ||
30 | INI_Entry *entry; | ||
31 | |||
32 | f = fopen(FileName,"rb"); | ||
33 | if (f == NULL) return NULL; | ||
34 | |||
35 | num = 0; | ||
36 | while(1) { | ||
37 | /* We read one line from file */ | ||
38 | bufferused = 0; | ||
39 | while (1) { | ||
40 | if (buffused == buffread) { | ||
41 | buffused = fread(buff,1,1000,f); | ||
42 | buffread = 0; | ||
43 | if (buffused == 0) { | ||
44 | free(buffer); free(buffer1); free(buffer2); | ||
45 | fclose(f); | ||
46 | return INI_head; | ||
47 | } | ||
48 | } | ||
49 | if (Unicode) { | ||
50 | if (num == 0) { | ||
51 | if (buffused == buffread) continue; | ||
52 | ch[0] = buff[buffread++]; | ||
53 | num = 1; | ||
54 | } | ||
55 | if (num == 1) { | ||
56 | if (buffused == buffread) continue; | ||
57 | ch[1] = buff[buffread++]; | ||
58 | num = 0; | ||
59 | } | ||
60 | if (level == -1) { | ||
61 | if (ch[0] == 0xFF && ch[1] == 0xFE) FFEEUnicode = true; | ||
62 | level = 0; | ||
63 | continue; | ||
64 | } | ||
65 | if (FFEEUnicode) { | ||
66 | ch[2] = ch[0]; ch[0] = ch[1]; ch[1] = ch[2]; | ||
67 | } | ||
68 | } else { | ||
69 | if (buffused == buffread) continue; | ||
70 | ch[0] = 0; | ||
71 | ch[1] = buff[buffread++]; | ||
72 | if (level == -1) level = 0; | ||
73 | } | ||
74 | if ((ch[0] == 0 && ch[1] == 13) || | ||
75 | (ch[0] == 0 && ch[1] == 10)) { | ||
76 | break; | ||
77 | } | ||
78 | buffer = realloc(buffer,bufferused+2); | ||
79 | buffer[bufferused] = ch[0]; | ||
80 | buffer[bufferused+1] = ch[1]; | ||
81 | bufferused = bufferused + 2; | ||
82 | } | ||
83 | // printf("line \"%s\"\n",DecodeUnicodeConsole(buffer)); | ||
84 | |||
85 | buffer1used = 0; | ||
86 | buffer2used = 0; | ||
87 | if (level == 1) level = 0; | ||
88 | if (level == 3 || level == 4 || level == 5) level = 2; | ||
89 | |||
90 | /* We parse read line */ | ||
91 | for (i=0;i<bufferused/2;i++) { | ||
92 | ch[0] = buffer[i*2]; | ||
93 | ch[1] = buffer[i*2+1]; | ||
94 | if (level == 0) { //search for name of section | ||
95 | if (ch[0] == 0 && ch[1] == '[') level = 1; | ||
96 | if (ch[0] == 0 && ch[1] == ';') break; | ||
97 | if (ch[0] == 0 && ch[1] == '#') break; | ||
98 | continue; | ||
99 | } | ||
100 | if (level == 1) { //section name | ||
101 | if (ch[0] == 0 && ch[1] == ']') { | ||
102 | if (buffer1used == 0) break; | ||
103 | if (Unicode) { | ||
104 | buffer1 = realloc(buffer1,buffer1used+2); | ||
105 | buffer1[buffer1used] = 0; | ||
106 | buffer1[buffer1used+1] = 0; | ||
107 | buffer1used = buffer1used + 2; | ||
108 | } else { | ||
109 | buffer1 = realloc(buffer1,buffer1used+1); | ||
110 | buffer1[buffer1used] = 0x00; | ||
111 | buffer1used = buffer1used + 1; | ||
112 | } | ||
113 | heading = (INI_Section *)malloc(sizeof(*heading)); | ||
114 | if (heading == NULL) { | ||
115 | free(buffer); free(buffer1); free(buffer2); | ||
116 | fclose(f); | ||
117 | return NULL; | ||
118 | } | ||
119 | heading->SectionName = (char *)malloc(buffer1used); | ||
120 | memcpy(heading->SectionName,buffer1,buffer1used); | ||
121 | heading->Prev = INI_info; | ||
122 | heading->Next = NULL; | ||
123 | if (INI_info != NULL) { | ||
124 | INI_info->Next = heading; | ||
125 | } else { | ||
126 | INI_head = heading; | ||
127 | } | ||
128 | INI_info = heading; | ||
129 | INI_info->SubEntries = NULL; | ||
130 | level = 2; | ||
131 | // printf("[%s]\n",DecodeUnicodeConsole(buffer1)); | ||
132 | break; | ||
133 | } | ||
134 | if (Unicode) { | ||
135 | buffer1 = realloc(buffer1,buffer1used+2); | ||
136 | buffer1[buffer1used] = ch[0]; | ||
137 | buffer1[buffer1used+1] = ch[1]; | ||
138 | buffer1used = buffer1used + 2; | ||
139 | } else { | ||
140 | buffer1 = realloc(buffer1,buffer1used+1); | ||
141 | buffer1[buffer1used] = ch[1]; | ||
142 | buffer1used = buffer1used + 1; | ||
143 | } | ||
144 | continue; | ||
145 | } | ||
146 | if (level == 2) { //search for key name | ||
147 | if (ch[0] == 0 && ch[1] == ';') break; | ||
148 | if (ch[0] == 0 && ch[1] == '#') break; | ||
149 | if (ch[0] == 0 && ch[1] == '[') { | ||
150 | level = 1; | ||
151 | continue; | ||
152 | } | ||
153 | if (Unicode) { | ||
154 | if (myiswspace(ch)) continue; | ||
155 | } else { | ||
156 | if (isspace((int) ch[1])) continue; | ||
157 | } | ||
158 | level = 3; | ||
159 | } | ||
160 | if (level == 3) { //key name | ||
161 | if (ch[0] == 0 && ch[1] == '=') { | ||
162 | if (buffer1used == 0) break; | ||
163 | while(1) { | ||
164 | if (Unicode) { | ||
165 | if (!myiswspace(buffer1+(buffer1used-2))) break; | ||
166 | buffer1used = buffer1used - 2; | ||
167 | } else { | ||
168 | if (!isspace((int)buffer1[buffer1used-1])) break; | ||
169 | buffer1used = buffer1used - 1; | ||
170 | } | ||
171 | } | ||
172 | level = 4; | ||
173 | continue; | ||
174 | } | ||
175 | if (Unicode) { | ||
176 | buffer1 = realloc(buffer1,buffer1used+2); | ||
177 | buffer1[buffer1used] = ch[0]; | ||
178 | buffer1[buffer1used+1] = ch[1]; | ||
179 | buffer1used = buffer1used + 2; | ||
180 | } else { | ||
181 | buffer1 = realloc(buffer1,buffer1used+1); | ||
182 | buffer1[buffer1used] = ch[1]; | ||
183 | buffer1used = buffer1used + 1; | ||
184 | } | ||
185 | } | ||
186 | if (level == 4) { //search for key value | ||
187 | if (Unicode) { | ||
188 | if (myiswspace(ch)) continue; | ||
189 | } else { | ||
190 | if (isspace((int) ch[1])) continue; | ||
191 | } | ||
192 | level = 5; | ||
193 | } | ||
194 | if (level == 5) { //key value | ||
195 | if (Unicode) { | ||
196 | buffer2 = realloc(buffer2,buffer2used+2); | ||
197 | buffer2[buffer2used] = ch[0]; | ||
198 | buffer2[buffer2used+1] = ch[1]; | ||
199 | buffer2used = buffer2used + 2; | ||
200 | } else { | ||
201 | buffer2 = realloc(buffer2,buffer2used+1); | ||
202 | buffer2[buffer2used] = ch[1]; | ||
203 | buffer2used = buffer2used + 1; | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | if (level == 5) { | ||
208 | if (buffer2used == 0) continue; | ||
209 | |||
210 | entry = (INI_Entry *)malloc(sizeof(*entry)); | ||
211 | if (entry == NULL) { | ||
212 | free(buffer); free(buffer1); free(buffer2); | ||
213 | fclose(f); | ||
214 | return NULL; | ||
215 | } | ||
216 | if (Unicode) { | ||
217 | buffer1 = realloc(buffer1,buffer1used+2); | ||
218 | buffer1[buffer1used] = 0; | ||
219 | buffer1[buffer1used+1] = 0; | ||
220 | buffer1used = buffer1used + 2; | ||
221 | buffer2 = realloc(buffer2,buffer2used+2); | ||
222 | buffer2[buffer2used] = 0; | ||
223 | buffer2[buffer2used+1] = 0; | ||
224 | buffer2used = buffer2used + 2; | ||
225 | } else { | ||
226 | buffer1 = realloc(buffer1,buffer1used+1); | ||
227 | buffer1[buffer1used] = 0x00; | ||
228 | buffer1used = buffer1used + 1; | ||
229 | buffer2 = realloc(buffer2,buffer2used+1); | ||
230 | buffer2[buffer2used] = 0x00; | ||
231 | buffer2used = buffer2used + 1; | ||
232 | } | ||
233 | // printf("\"%s\"=\"%s\"\n",buffer1,buffer2); | ||
234 | // printf("\"%s\"=",DecodeUnicodeConsole(buffer1)); | ||
235 | // printf("\"%s\"\n",DecodeUnicodeConsole(buffer2)); | ||
236 | |||
237 | entry->EntryName = (char *)malloc(buffer1used); | ||
238 | memcpy(entry->EntryName,buffer1,buffer1used); | ||
239 | |||
240 | entry->EntryValue = (char *)malloc(buffer2used); | ||
241 | memcpy(entry->EntryValue,buffer2,buffer2used); | ||
242 | |||
243 | entry->Prev = NULL; | ||
244 | entry->Next = INI_info->SubEntries; | ||
245 | if (INI_info->SubEntries != NULL) INI_info->SubEntries->Prev = entry; | ||
246 | INI_info->SubEntries = entry; | ||
247 | } | ||
248 | } | ||
249 | free(buffer); free(buffer1); free(buffer2); | ||
250 | fclose(f); | ||
251 | return INI_head; | ||
252 | } | ||
253 | |||
254 | /* | ||
255 | * Search for key value in file in Windows INI format style | ||
256 | * Returns found value or NULL | ||
257 | */ | ||
258 | unsigned char *INI_GetValue(INI_Section *cfg, unsigned char *section, unsigned char *key, bool Unicode) | ||
259 | { | ||
260 | INI_Section *sec; | ||
261 | INI_Entry *ent; | ||
262 | |||
263 | if (cfg == NULL || section == NULL || key == NULL) return NULL; | ||
264 | |||
265 | if (Unicode) { | ||
266 | /* Search for section */ | ||
267 | sec = cfg; | ||
268 | while (sec != NULL) { | ||
269 | if (mywstrncasecmp(section, sec->SectionName, 0)) { | ||
270 | /* Search for key inside section */ | ||
271 | ent = sec->SubEntries; | ||
272 | while (ent != NULL) { | ||
273 | if (mywstrncasecmp(key,ent->EntryName,0)) { | ||
274 | return ent->EntryValue; | ||
275 | } | ||
276 | ent = ent->Next; | ||
277 | } | ||
278 | } | ||
279 | sec = sec->Next; | ||
280 | } | ||
281 | } else { | ||
282 | /* Search for section */ | ||
283 | sec = cfg; | ||
284 | while (sec != NULL) { | ||
285 | if (mystrncasecmp(section, sec->SectionName, 0)) { | ||
286 | /* Search for key inside section */ | ||
287 | ent = sec->SubEntries; | ||
288 | while (ent != NULL) { | ||
289 | if (mystrncasecmp(key,ent->EntryName,0)) { | ||
290 | return ent->EntryValue; | ||
291 | } | ||
292 | ent = ent->Next; | ||
293 | } | ||
294 | } | ||
295 | sec = sec->Next; | ||
296 | } | ||
297 | } | ||
298 | return NULL; | ||
299 | } | ||
300 | |||
301 | /* Return last value in specified section */ | ||
302 | INI_Entry *INI_FindLastSectionEntry(INI_Section *file_info, unsigned char *section, bool Unicode) | ||
303 | { | ||
304 | INI_Section *h; | ||
305 | INI_Entry*e; | ||
306 | |||
307 | e = NULL; | ||
308 | /* First find our section */ | ||
309 | for (h = file_info; h != NULL; h = h->Next) { | ||
310 | if (Unicode) { | ||
311 | if (mywstrncasecmp(section, h->SectionName, 0)) { | ||
312 | e = h->SubEntries; | ||
313 | break; | ||
314 | } | ||
315 | } else { | ||
316 | if (mystrncasecmp(section, h->SectionName, 0)) { | ||
317 | e = h->SubEntries; | ||
318 | break; | ||
319 | } | ||
320 | } | ||
321 | } | ||
322 | |||
323 | if (e == NULL) return NULL; | ||
324 | |||
325 | /* Goes into last value in section */ | ||
326 | while (e->Next != NULL) e = e->Next; | ||
327 | return e; | ||
328 | } | ||
329 | |||
330 | /* How should editor hadle tabs in this file? Add editor commands here. | ||
331 | * vim: noexpandtab sw=8 ts=8 sts=8: | ||
332 | */ | ||