7 A Linux/Unix toolset and driver for Nokia mobile phones.
9 Copyright (C) 1999, 2000 Hugh Blemings & Pavel JanÃk ml.
11 Released under the terms of the GNU GPL, see file COPYING for more details.
13 Config file (/etc/gnokiirc and ~/.gnokiirc) reader.
15 Modified from code by Tim Potter.
18 Revision 1.1.1.1.8.1 2001/11/25 23:10:58 short
19 * ... - new cfgreader.c/CFG_GetForeach()
20 some "const" keywords written - they are missing almost everywhere in Gnokii!
21 "CFG_info" is now global public symbol
22 * Global symbols became IMO obsolete: {model,port,initlength,connection,bindir}
23 stdout/stderr are de-buffered (cfgreading is upon startup)
24 * I know that it doesn't belong here but currently there is now generic
25 application init function anywhere.
26 * stdout/stderr de-buffering is already donw at various weird places all
29 Revision 1.1.1.1 2001/11/25 21:58:58 short
30 :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Sun Nov 25 22:56 CET 2001
32 Revision 1.16 2001/11/14 10:46:12 pkot
33 Small cleanup with __unices__
35 Revision 1.15 2001/06/10 11:24:57 machek
36 Kill "slash star" inside comment.
38 Revision 1.14 2001/03/19 23:43:45 pkot
39 Solaris/ *BSD '#if defined' cleanup
41 Revision 1.13 2001/03/13 01:21:38 pkot
42 *BSD updates (Bert Driehuis)
44 Revision 1.12 2001/01/08 15:11:36 pkot
45 Documentation updates.
46 Fixed some bugs and removed FIXMEs.
47 We need to move some stuff from configure.in to aclocal.m4
49 Revision 1.11 2001/01/02 09:09:07 pkot
50 Misc fixes and updates.
52 Revision 1.10 2000/12/19 16:18:15 pkot
53 configure script updates and added shared function for configfile reading
66 #include "cfgreader.h"
68 struct CFG_Header *CFG_Info;
70 /* Read configuration information from a ".INI" style file */
71 struct CFG_Header *CFG_ReadFile(char *filename)
76 struct CFG_Header *cfg_info = NULL, *cfg_head = NULL;
79 if (filename == NULL) {
84 if ((buf = (char *)malloc(255)) == NULL) {
89 if ((handle = fopen(filename, "r")) == NULL) {
91 fprintf( stderr, "CFG_ReadFile - open %s: %s\n", filename, strerror(errno));
97 fprintf( stderr, "Opened configuration file %s\n", filename );
100 /* Iterate over lines in the file */
101 while (fgets(buf, 255, handle) != NULL) {
105 /* Strip leading, trailing whitespace */
106 while(isspace((int) *line))
109 while((strlen(line) > 0) && isspace((int) line[strlen(line) - 1]))
110 line[strlen(line) - 1] = '\0';
112 /* Ignore blank lines and comments */
113 if ((*line == '\n') || (*line == '\0') || (*line == '#'))
116 /* Look for "headings" enclosed in square brackets */
117 if ((line[0] == '[') && (line[strlen(line) - 1] == ']')) {
118 struct CFG_Header *heading;
120 /* Allocate new heading entry */
121 if ((heading = (struct CFG_Header *)malloc(sizeof(*heading))) == NULL) {
126 memset(heading, '\0', sizeof(*heading));
129 line[strlen(line) - 1] = '\0';
131 /* FIXME: strdup is not ANSI C compliant. */
132 heading->section = strdup(line);
134 /* Add to tail of list */
135 heading->prev = cfg_info;
137 if (cfg_info != NULL) {
138 cfg_info->next = heading;
140 /* Store copy of head of list for return value */
147 fprintf(stderr, "Added new section %s\n", heading->section);
149 /* Go on to next line */
154 /* Process key/value line */
156 if ((strchr(line, '=') != NULL) && cfg_info != NULL) {
157 struct CFG_Entry *entry;
160 /* Allocate new entry */
161 if ((entry = (struct CFG_Entry *)malloc(sizeof(*entry))) == NULL) {
166 memset(entry, '\0', sizeof(*entry));
168 value = strchr(line, '=');
169 *value = '\0'; /* Split string */
172 while(isspace((int) *value)) { /* Remove leading white */
176 entry->value = strdup(value);
178 while((strlen(line) > 0) && isspace((int) line[strlen(line) - 1])) {
179 line[strlen(line) - 1] = '\0'; /* Remove trailing white */
182 /* FIXME: strdup is not ANSI C compliant. */
183 entry->key = strdup(line);
185 /* Add to head of list */
187 entry->next = cfg_info->entries;
189 if (cfg_info->entries != NULL) {
190 cfg_info->entries->prev = entry;
193 cfg_info->entries = entry;
196 fprintf(stderr, "Adding key/value %s/%s\n", entry->key, entry->value);
198 /* Go on to next line */
202 /* Line not part of any heading */
203 fprintf(stderr, "Orphaned line: %s\n", line);
206 /* Return pointer to configuration information */
210 /* Write configuration information to a config file */
212 int CFG_WriteFile(struct CFG_Header *cfg, char *filename)
214 /* Not implemented - tricky to do and preserve comments */
220 * Find the value of a key in a config file. Return value associated
221 * with key or NULL if no such key exists.
224 char *CFG_Get(struct CFG_Header *cfg, const char *section, const char *key)
226 struct CFG_Header *h;
229 if ((cfg == NULL) || (section == NULL) || (key == NULL)) {
233 /* Search for section name */
234 for (h = cfg; h != NULL; h = h->next) {
235 if (strcmp(section, h->section) == 0) {
236 /* Search for key within section */
237 for (e = h->entries; e != NULL; e = e->next) {
238 if (strcmp(key, e->key) == 0) {
245 /* Key not found in section */
250 * Return all the entries of the fiven section.
253 void CFG_GetForeach(struct CFG_Header *cfg, const char *section, CFG_GetForeach_func func)
255 struct CFG_Header *h;
258 if ((cfg == NULL) || (section == NULL) || (func == NULL)) {
262 /* Search for section name */
263 for (h = cfg; h != NULL; h = h->next) {
264 if (strcmp(section, h->section) == 0) {
265 /* Search for key within section */
266 for (e = h->entries; e != NULL; e = e->next)
267 (*func)(section,e->key,e->value);
272 /* Set the value of a key in a config file. Return the new value if
273 the section/key can be found, else return NULL. */
275 char *CFG_Set(struct CFG_Header *cfg, char *section, char *key,
278 struct CFG_Header *h;
281 if ((cfg == NULL) || (section == NULL) || (key == NULL) ||
286 /* Search for section name */
287 for (h = cfg; h != NULL; h = h->next) {
288 if (strcmp(section, h->section) == 0) {
289 /* Search for key within section */
290 for (e = h->entries; e != NULL; e = e->next) {
291 if ((e->key != NULL) && strcmp(key, e->key) == 0) {
292 /* Found - set value */
294 /* FIXME: strdup is not ANSI C compliant. */
295 e->key = strdup(value);
301 /* Key not found in section */
305 int readconfig(char **model, char **port, char **initlength,
306 char **connection, char **bindir)
310 char *DefaultConnection = "serial";
311 char *DefaultBindir = "/usr/local/sbin/";
313 /* I know that it doesn't belong here but currently there is now generic
314 * application init function anywhere.
316 setvbuf(stdout, NULL, _IONBF, 0);
317 setvbuf(stderr, NULL, _IONBF, 0);
320 homedir = getenv("HOMEDRIVE");
321 strncpy(rcfile, homedir ? homedir : "", 200);
322 homedir = getenv("HOMEPATH");
323 strncat(rcfile, homedir ? homedir : "", 200);
324 strncat(rcfile, "\\_gnokiirc", 200);
326 homedir = getenv("HOME");
327 if (homedir) strncpy(rcfile, homedir, 200);
328 strncat(rcfile, "/.gnokiirc", 200);
331 /* Try opening .gnokirc from users home directory first */
332 if ((CFG_Info = CFG_ReadFile(rcfile)) == NULL) {
333 /* It failed so try for /etc/gnokiirc */
334 if ((CFG_Info = CFG_ReadFile("/etc/gnokiirc")) == NULL) {
335 /* That failed too so exit */
336 fprintf(stderr, _("Couldn't open %s or /etc/gnokiirc. Exiting now...\n"), rcfile);
341 (char *)*model = CFG_Get(CFG_Info, "global", "model");
343 fprintf(stderr, _("Config error - no model specified. Exiting now...\n"));
347 (char *)*port = CFG_Get(CFG_Info, "global", "port");
349 fprintf(stderr, _("Config error - no port specified. Exiting now...\n"));
353 (char *)*initlength = CFG_Get(CFG_Info, "global", "initlength");
354 if (!*initlength) (char *)*initlength = "default";
356 (char *)*connection = CFG_Get(CFG_Info, "global", "connection");
357 if (!*connection) (char *)*connection = DefaultConnection;
359 (char *)*bindir = CFG_Get(CFG_Info, "global", "bindir");
360 if (!*bindir) (char *)*bindir = DefaultBindir;