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.2 2002/04/03 00:07:51 short
19 Found in "gnokii-working" directory, some November-patches version
21 Revision 1.15 2001/06/10 11:24:57 machek
22 Kill "slash star" inside comment.
24 Revision 1.14 2001/03/19 23:43:45 pkot
25 Solaris/ *BSD '#if defined' cleanup
27 Revision 1.13 2001/03/13 01:21:38 pkot
28 *BSD updates (Bert Driehuis)
30 Revision 1.12 2001/01/08 15:11:36 pkot
31 Documentation updates.
32 Fixed some bugs and removed FIXMEs.
33 We need to move some stuff from configure.in to aclocal.m4
35 Revision 1.11 2001/01/02 09:09:07 pkot
36 Misc fixes and updates.
38 Revision 1.10 2000/12/19 16:18:15 pkot
39 configure script updates and added shared function for configfile reading
55 #include "cfgreader.h"
57 struct CFG_Header *CFG_Info;
59 /* Read configuration information from a ".INI" style file */
60 struct CFG_Header *CFG_ReadFile(char *filename)
65 struct CFG_Header *cfg_info = NULL, *cfg_head = NULL;
68 if (filename == NULL) {
73 if ((buf = (char *)malloc(255)) == NULL) {
78 if ((handle = fopen(filename, "r")) == NULL) {
80 fprintf( stderr, "CFG_ReadFile - open %s: %s\n", filename, strerror(errno));
86 fprintf( stderr, "Opened configuration file %s\n", filename );
89 /* Iterate over lines in the file */
90 while (fgets(buf, 255, handle) != NULL) {
94 /* Strip leading, trailing whitespace */
95 while(isspace((int) *line))
98 while((strlen(line) > 0) && isspace((int) line[strlen(line) - 1]))
99 line[strlen(line) - 1] = '\0';
101 /* Ignore blank lines and comments */
102 if ((*line == '\n') || (*line == '\0') || (*line == '#'))
105 /* Look for "headings" enclosed in square brackets */
106 if ((line[0] == '[') && (line[strlen(line) - 1] == ']')) {
107 struct CFG_Header *heading;
109 /* Allocate new heading entry */
110 if ((heading = (struct CFG_Header *)malloc(sizeof(*heading))) == NULL) {
115 memset(heading, '\0', sizeof(*heading));
118 line[strlen(line) - 1] = '\0';
120 /* FIXME: strdup is not ANSI C compliant. */
121 heading->section = strdup(line);
123 /* Add to tail of list */
124 heading->prev = cfg_info;
126 if (cfg_info != NULL) {
127 cfg_info->next = heading;
129 /* Store copy of head of list for return value */
136 fprintf(stderr, "Added new section %s\n", heading->section);
138 /* Go on to next line */
143 /* Process key/value line */
145 if ((strchr(line, '=') != NULL) && cfg_info != NULL) {
146 struct CFG_Entry *entry;
149 /* Allocate new entry */
150 if ((entry = (struct CFG_Entry *)malloc(sizeof(*entry))) == NULL) {
155 memset(entry, '\0', sizeof(*entry));
157 value = strchr(line, '=');
158 *value = '\0'; /* Split string */
161 while(isspace((int) *value)) { /* Remove leading white */
165 entry->value = strdup(value);
167 while((strlen(line) > 0) && isspace((int) line[strlen(line) - 1])) {
168 line[strlen(line) - 1] = '\0'; /* Remove trailing white */
171 /* FIXME: strdup is not ANSI C compliant. */
172 entry->key = strdup(line);
174 /* Add to head of list */
176 entry->next = cfg_info->entries;
178 if (cfg_info->entries != NULL) {
179 cfg_info->entries->prev = entry;
182 cfg_info->entries = entry;
185 fprintf(stderr, "Adding key/value %s/%s\n", entry->key, entry->value);
187 /* Go on to next line */
191 /* Line not part of any heading */
192 fprintf(stderr, "Orphaned line: %s\n", line);
195 /* Return pointer to configuration information */
199 /* Write configuration information to a config file */
201 int CFG_WriteFile(struct CFG_Header *cfg, char *filename)
203 /* Not implemented - tricky to do and preserve comments */
209 * Find the value of a key in a config file. Return value associated
210 * with key or NULL if no such key exists.
213 char *CFG_Get(struct CFG_Header *cfg, const char *section, const char *key)
215 struct CFG_Header *h;
218 if ((cfg == NULL) || (section == NULL) || (key == NULL)) {
222 /* Search for section name */
223 for (h = cfg; h != NULL; h = h->next) {
224 if (strcmp(section, h->section) == 0) {
225 /* Search for key within section */
226 for (e = h->entries; e != NULL; e = e->next) {
227 if (strcmp(key, e->key) == 0) {
234 /* Key not found in section */
239 * Return all the entries of the fiven section.
242 void CFG_GetForeach(struct CFG_Header *cfg, const char *section, CFG_GetForeach_func func)
244 struct CFG_Header *h;
247 if ((cfg == NULL) || (section == NULL) || (func == NULL)) {
251 /* Search for section name */
252 for (h = cfg; h != NULL; h = h->next) {
253 if (strcmp(section, h->section) == 0) {
254 /* Search for key within section */
255 for (e = h->entries; e != NULL; e = e->next)
256 (*func)(section,e->key,e->value);
261 /* Set the value of a key in a config file. Return the new value if
262 the section/key can be found, else return NULL. */
264 char *CFG_Set(struct CFG_Header *cfg, char *section, char *key,
267 struct CFG_Header *h;
270 if ((cfg == NULL) || (section == NULL) || (key == NULL) ||
275 /* Search for section name */
276 for (h = cfg; h != NULL; h = h->next) {
277 if (strcmp(section, h->section) == 0) {
278 /* Search for key within section */
279 for (e = h->entries; e != NULL; e = e->next) {
280 if ((e->key != NULL) && strcmp(key, e->key) == 0) {
281 /* Found - set value */
283 /* FIXME: strdup is not ANSI C compliant. */
284 e->key = strdup(value);
290 /* Key not found in section */
294 int readconfig(char **model, char **port, char **initlength,
295 char **connection, char **bindir)
299 char *DefaultConnection = "serial";
300 char *DefaultBindir = "/usr/local/sbin/";
302 /* I know that it doesn't belong here but currently there is now generic
303 * application init function anywhere.
305 setvbuf(stdout, NULL, _IONBF, 0);
306 setvbuf(stderr, NULL, _IONBF, 0);
309 homedir = getenv("HOMEDRIVE");
310 strncpy(rcfile, homedir ? homedir : "", 200);
311 homedir = getenv("HOMEPATH");
312 strncat(rcfile, homedir ? homedir : "", 200);
313 strncat(rcfile, "\\_gnokiirc", 200);
315 homedir = getenv("HOME");
316 if (homedir) strncpy(rcfile, homedir, 200);
317 strncat(rcfile, "/.gnokiirc", 200);
320 /* Try opening .gnokirc from users home directory first */
321 if ((CFG_Info = CFG_ReadFile(rcfile)) == NULL) {
322 /* It failed so try for /etc/gnokiirc */
323 if ((CFG_Info = CFG_ReadFile("/etc/gnokiirc")) == NULL) {
324 /* That failed too so exit */
325 fprintf(stderr, _("Couldn't open %s or /etc/gnokiirc. Exiting now...\n"), rcfile);
330 (char *)*model = CFG_Get(CFG_Info, "global", "model");
332 fprintf(stderr, _("Config error - no model specified. Exiting now...\n"));
336 (char *)*port = CFG_Get(CFG_Info, "global", "port");
338 fprintf(stderr, _("Config error - no port specified. Exiting now...\n"));
342 (char *)*initlength = CFG_Get(CFG_Info, "global", "initlength");
343 if (!*initlength) (char *)*initlength = "default";
345 (char *)*connection = CFG_Get(CFG_Info, "global", "connection");
346 if (!*connection) (char *)*connection = DefaultConnection;
348 (char *)*bindir = CFG_Get(CFG_Info, "global", "bindir");
349 if (!*bindir) (char *)*bindir = DefaultBindir;