summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/misc/cfg.c
Unidiff
Diffstat (limited to 'gammu/emb/common/misc/cfg.c') (more/less context) (ignore whitespace changes)
-rw-r--r--gammu/emb/common/misc/cfg.c332
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 */
21INI_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 */
258unsigned 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 */
302INI_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 */