]> icculus.org git repositories - taylor/freespace2.git/blob - src/osapi/osregistry-unix.cpp
net fixes
[taylor/freespace2.git] / src / osapi / osregistry-unix.cpp
1 #include "pstypes.h"
2 #include "osregistry.h"
3 #undef malloc
4 #undef free
5 #undef strdup
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <ctype.h>
10
11 char *Osreg_company_name = "Volition";
12 char *Osreg_class_name = "Freespace2Class";
13 #if defined(FS2_DEMO)
14 char *Osreg_app_name = "FreeSpace2Demo";
15 char *Osreg_title = "Freespace 2 Demo";
16 #define PROFILE_NAME "FreeSpace2Demo.ini"
17 #elif defined(OEM_BUILD)
18 char *Osreg_app_name = "FreeSpace2OEM";
19 char *Osreg_title = "Freespace 2 OEM";
20 #define PROFILE_NAME "FreeSpace2OEM.ini"
21 #else
22 char *Osreg_app_name = "FreeSpace2";
23 char *Osreg_title = "Freespace 2";
24 #define PROFILE_NAME "FreeSpace2.ini"
25 #endif
26
27 #define DEFAULT_SECTION "Default"
28
29 typedef struct KeyValue
30 {
31         char *key;
32         char *value;
33         
34         KeyValue *next;
35 } KeyValue;
36
37 typedef struct Section
38 {
39         char *name;
40         
41         KeyValue *pairs;
42         Section *next;
43 } Section;
44         
45 typedef struct Profile
46 {
47         Section *sections;
48 } Profile;
49
50 static char *read_line_from_file(FILE *fp)
51 {
52         char *buf, *buf_start;
53         int buflen, len, eol;
54         
55         buflen = 80;
56         buf = (char *)malloc(buflen);
57         buf_start = buf;
58         eol = 0;
59         
60         do {
61                 if (buf == NULL)
62                         return NULL;
63                 
64                 if (fgets(buf_start, 80, fp) == NULL)
65                         return NULL;
66                 
67                 len = strlen(buf_start);
68                 
69                 if (buf_start[len-1] == '\n') {
70                         buf_start[len-1] = 0;
71                         eol = 1;
72                 } else {
73                         buflen += 80;
74                         
75                         buf = (char *)realloc(buf, buflen);
76                         
77                         /* be sure to skip over the proper amount of nulls */
78                         buf_start = buf+(buflen-80)-(buflen/80)+1;
79                 }
80         } while (!eol);
81         
82         return buf;
83 }
84
85 static char *trim_string(char *str)
86 {
87         char *ptr;
88         
89         if (str == NULL)
90                 return NULL;
91         
92         /* kill any comment */
93         ptr = strchr(str, ';');
94         if (ptr)
95                 *ptr = 0;
96         
97         ptr = str+strlen(str)-1;
98         while (*ptr && isspace(*ptr)) {
99                 ptr--;
100         }
101         
102         if (*ptr) {
103                 ptr++;
104                 *ptr = 0;
105         }
106         
107         ptr = str;
108         while (*ptr && isspace(*ptr)) {
109                 ptr++;
110         }
111         
112         return ptr;
113 }
114
115 static Profile *profile_read(char *file)
116 {
117         FILE *fp = fopen(file, "r");
118         if (fp == NULL)
119                 return NULL;
120         
121         Profile *profile = (Profile *)malloc(sizeof(Profile));
122         profile->sections = NULL;
123         
124         Section **sp_ptr = &(profile->sections);
125         Section *sp = NULL;
126
127         KeyValue **kvp_ptr = NULL;
128                 
129         char *str;
130         while ((str = read_line_from_file(fp)) != NULL) {
131                 char *ptr = trim_string(str);
132                 
133                 if (*ptr == '[') {
134                         ptr++;
135                         
136                         char *pend = strchr(ptr, ']');
137                         if (pend != NULL) {
138                                 // if (pend[1]) { /* trailing garbage! */ }
139                                 
140                                 *pend = 0;                              
141                                 
142                                 if (*ptr) {
143                                         sp = (Section *)malloc(sizeof(Section));
144                                         sp->next = NULL;
145                                 
146                                         sp->name = strdup(ptr);
147                                         sp->pairs = NULL;
148                                         
149                                         *sp_ptr = sp;
150                                         sp_ptr = &(sp->next);
151                                         
152                                         kvp_ptr = &(sp->pairs);
153                                 } // else { /* null name! */ }
154                         } // else { /* incomplete section name! */ }
155                 } else {
156                         if (*ptr) {
157                                 char *key = ptr;
158                                 char *value = NULL;
159                                 
160                                 ptr = strchr(ptr, '=');
161                                 if (ptr != NULL) {
162                                         *ptr = 0;
163                                         ptr++;
164                                         
165                                         value = ptr;
166                                 } // else { /* random garbage! */ }
167                                 
168                                 if (key && *key && value /* && *value */) {
169                                         if (sp != NULL) {
170                                                 KeyValue *kvp = (KeyValue *)malloc(sizeof(KeyValue));
171                                                 
172                                                 kvp->key = strdup(key);
173                                                 kvp->value = strdup(value);
174                                                 
175                                                 kvp->next = NULL;
176                                                 
177                                                 *kvp_ptr = kvp;
178                                                 kvp_ptr = &(kvp->next);
179                                         } // else { /* key/value with no section! */
180                                 } // else { /* malformed key/value entry! */ }
181                         } // else it's just a comment or empty string
182                 }
183                                 
184                 free(str);
185         }
186         
187         fclose(fp);
188
189         return profile;
190 }
191
192 static void profile_free(Profile *profile)
193 {
194         if (profile == NULL)
195                 return;
196                 
197         Section *sp = profile->sections;
198         while (sp != NULL) {
199                 Section *st = sp;
200                 KeyValue *kvp = sp->pairs;
201                 
202                 while (kvp != NULL) {
203                         KeyValue *kvt = kvp;
204                         
205                         free(kvp->key);
206                         free(kvp->value);
207                         
208                         kvp = kvp->next;
209                         free(kvt);
210                 }
211                 
212                 free(sp->name);
213                 
214                 sp = sp->next;
215                 free(st);
216         }
217         
218         free(profile);
219 }
220
221 static Profile *profile_update(Profile *profile, char *section, char *key, char *value)
222 {
223         if (profile == NULL) {
224                 profile = (Profile *)malloc(sizeof(Profile));
225                 
226                 profile->sections = NULL;
227         }
228         
229         KeyValue *kvp;
230         
231         Section **sp_ptr = &(profile->sections);
232         Section *sp = profile->sections;
233         while (sp != NULL) {
234                 if (strcmp(section, sp->name) == 0) {
235                         KeyValue **kvp_ptr = &(sp->pairs);
236                         kvp = sp->pairs;
237                         
238                         while (kvp != NULL) {
239                                 if (strcmp(key, kvp->key) == 0) {
240                                         free(kvp->value);
241                                         
242                                         kvp->value = strdup(value);
243                                         
244                                         /* all done */
245                                         return profile;
246                                 }
247                                 
248                                 kvp_ptr = &(kvp->next);
249                                 kvp = kvp->next;
250                         }
251                         
252                         /* key not found */
253                         kvp = (KeyValue *)malloc(sizeof(KeyValue));
254                         kvp->next = NULL;
255                         kvp->key = strdup(key);
256                         kvp->value = strdup(value);
257                         
258                         *kvp_ptr = kvp;
259                         
260                         /* all done */
261                         return profile;
262                 }
263                 
264                 sp_ptr = &(sp->next);
265                 sp = sp->next;
266         }
267         
268         /* section not found */
269         sp = (Section *)malloc(sizeof(Section));
270         sp->next = NULL;
271         sp->name = strdup(section);
272         
273         kvp = (KeyValue *)malloc(sizeof(KeyValue));
274         kvp->next = NULL;
275         kvp->key = strdup(key);
276         kvp->value = strdup(value);
277         
278         sp->pairs = kvp;
279         
280         *sp_ptr = sp;
281         
282         return profile;
283 }
284
285 static char *profile_get_value(Profile *profile, char *section, char *key)
286 {
287         if (profile == NULL)
288                 return NULL;
289         
290         Section *sp = profile->sections;
291         while (sp != NULL) {
292                 if (strcmp(section, sp->name) == 0) {
293                         KeyValue *kvp = sp->pairs;
294                 
295                         while (kvp != NULL) {
296                                 if (strcmp(key, kvp->key) == 0) {
297                                         return kvp->value;
298                                 }
299                                 kvp = kvp->next;
300                         }
301                 }
302                 
303                 sp = sp->next;
304         }
305         
306         /* not found */
307         return NULL;
308 }
309
310 static void profile_save(Profile *profile, char *file)
311 {
312         FILE *fp;
313         
314         if (profile == NULL)
315                 return;
316                 
317         fp = fopen(file, "w");
318         if (fp == NULL)
319                 return;
320         
321         Section *sp = profile->sections;
322         while (sp != NULL) {
323                 fprintf(fp, "[%s]\n", sp->name);
324                 
325                 KeyValue *kvp = sp->pairs;
326                 while (kvp != NULL) {
327                         fprintf(fp, "%s=%s\n", kvp->key, kvp->value);
328                         kvp = kvp->next;
329                 }
330                 
331                 fprintf(fp, "\n");
332                 
333                 sp = sp->next;
334         }
335         
336         fclose(fp);
337 }
338
339 static char tmp_string_data[1024];
340
341 char *os_config_read_string(char *section, char *name, char *default_value)
342 {
343         Profile *p = profile_read(PROFILE_NAME);
344         
345         if (section == NULL)
346                 section = DEFAULT_SECTION;
347                 
348         char *ptr = profile_get_value(p, section, name);
349         if (ptr != NULL) {
350                 strncpy(tmp_string_data, ptr, 1023);
351                 default_value = tmp_string_data;
352         }
353         
354         profile_free(p);
355         
356         return default_value;
357 }
358
359 unsigned int os_config_read_uint(char *section, char *name, unsigned int default_value)
360 {
361         Profile *p = profile_read(PROFILE_NAME);
362         
363         if (section == NULL)
364                 section = DEFAULT_SECTION;
365                 
366         char *ptr = profile_get_value(p, section, name);
367         if (ptr != NULL) {
368                 default_value = atoi(ptr);
369         }
370         
371         profile_free(p);
372         
373         return default_value;
374 }
375
376 void os_config_write_string(char *section, char *name, char *value)
377 {
378         Profile *p = profile_read(PROFILE_NAME);
379         
380         if (section == NULL)
381                 section = DEFAULT_SECTION;
382                 
383         p = profile_update(p, section, name, value);
384         profile_save(p, PROFILE_NAME);
385         profile_free(p);        
386 }
387
388 void os_config_write_uint(char *section, char *name, unsigned int value)
389 {
390         static char buf[21];
391         
392         snprintf(buf, 20, "%u", value);
393         
394         Profile *p = profile_read(PROFILE_NAME);
395         
396         if (section == NULL)
397                 section = DEFAULT_SECTION;
398         
399         p = profile_update(p, section, name, buf);
400         profile_save(p, PROFILE_NAME);
401         profile_free(p);
402 }