X-Git-Url: http://git.jankratochvil.net/?p=gnokii.git;a=blobdiff_plain;f=common%2Ffiles%2Fcfgreader.c;fp=common%2Ffiles%2Fcfgreader.c;h=9908cc1fd0a6641d5cb82cfd8694838413b11b73;hp=0000000000000000000000000000000000000000;hb=2e0972b02d101bb0d8e9d3e15d2ac80def491a63;hpb=cc37b87508c91b5d4f21fd4bbc298104ae7de1dc diff --git a/common/files/cfgreader.c b/common/files/cfgreader.c new file mode 100644 index 0000000..9908cc1 --- /dev/null +++ b/common/files/cfgreader.c @@ -0,0 +1,339 @@ +/* + + $Id$ + + G N O K I I + + A Linux/Unix toolset and driver for Nokia mobile phones. + + Released under the terms of the GNU GPL, see file COPYING for more details. + + Config file (/etc/gnokiirc and ~/.gnokiirc) reader. + + Modified from code by Tim Potter. + +*/ + +#include "misc.h" + +#include +#include +#include +#if __unices__ +# include +#endif +#include +#include + +#include "files/cfgreader.h" + +/* Read configuration information from a ".INI" style file */ +struct CFG_Header *CFG_ReadFile(char *filename) +{ + FILE *handle; + char *line; + char *buf; + struct CFG_Header *cfg_info = NULL, *cfg_head = NULL; + + /* Error check */ + if (filename == NULL) { + return NULL; + } + + /* Initialisation */ + if ((buf = (char *)malloc(255)) == NULL) { + return NULL; + } + + /* Open file */ + if ((handle = fopen(filename, "r")) == NULL) { +#ifdef DEBUG + fprintf( stderr, "CFG_ReadFile - open %s: %s\n", filename, strerror(errno)); +#endif /* DEBUG */ + return NULL; + } +#ifdef DEBUG + else + fprintf( stderr, "Opened configuration file %s\n", filename ); +#endif /* DEBUG */ + + /* Iterate over lines in the file */ + while (fgets(buf, 255, handle) != NULL) { + + line = buf; + + /* Strip leading, trailing whitespace */ + while(isspace((int) *line)) + line++; + + while((strlen(line) > 0) && isspace((int) line[strlen(line) - 1])) + line[strlen(line) - 1] = '\0'; + + /* Ignore blank lines and comments */ + if ((*line == '\n') || (*line == '\0') || (*line == '#')) + continue; + + /* Look for "headings" enclosed in square brackets */ + if ((line[0] == '[') && (line[strlen(line) - 1] == ']')) { + struct CFG_Header *heading; + + /* Allocate new heading entry */ + if ((heading = (struct CFG_Header *)malloc(sizeof(*heading))) == NULL) { + return NULL; + } + + /* Fill in fields */ + memset(heading, '\0', sizeof(*heading)); + + line++; + line[strlen(line) - 1] = '\0'; + + /* FIXME: strdup is not ANSI C compliant. */ + heading->section = strdup(line); + + /* Add to tail of list */ + heading->prev = cfg_info; + + if (cfg_info != NULL) { + cfg_info->next = heading; + } else { + /* Store copy of head of list for return value */ + cfg_head = heading; + } + + cfg_info = heading; + +#ifdef DEBUG + fprintf(stderr, "Added new section %s\n", heading->section); +#endif + /* Go on to next line */ + + continue; + } + + /* Process key/value line */ + + if ((strchr(line, '=') != NULL) && cfg_info != NULL) { + struct CFG_Entry *entry; + char *value; + + /* Allocate new entry */ + if ((entry = (struct CFG_Entry *)malloc(sizeof(*entry))) == NULL) { + return NULL; + } + + /* Fill in fields */ + memset(entry, '\0', sizeof(*entry)); + + value = strchr(line, '='); + *value = '\0'; /* Split string */ + value++; + + while(isspace((int) *value)) { /* Remove leading white */ + value++; + } + + entry->value = strdup(value); + + while((strlen(line) > 0) && isspace((int) line[strlen(line) - 1])) { + line[strlen(line) - 1] = '\0'; /* Remove trailing white */ + } + + /* FIXME: strdup is not ANSI C compliant. */ + entry->key = strdup(line); + + /* Add to head of list */ + + entry->next = cfg_info->entries; + + if (cfg_info->entries != NULL) { + cfg_info->entries->prev = entry; + } + + cfg_info->entries = entry; + +#ifdef DEBUG + fprintf(stderr, "Adding key/value %s/%s\n", entry->key, entry->value); +#endif + /* Go on to next line */ + continue; + } + + /* Line not part of any heading */ + fprintf(stderr, "Orphaned line: %s\n", line); + } + + /* Return pointer to configuration information */ + return cfg_head; +} + +/* Write configuration information to a config file */ + +int CFG_WriteFile(struct CFG_Header *cfg, char *filename) +{ + /* Not implemented - tricky to do and preserve comments */ + + return 0; +} + +/* + * Find the value of a key in a config file. Return value associated + * with key or NULL if no such key exists. + */ + +char *CFG_Get(struct CFG_Header *cfg, char *section, char *key) +{ + struct CFG_Header *h; + struct CFG_Entry *e; + + if ((cfg == NULL) || (section == NULL) || (key == NULL)) { + return NULL; + } + + /* Search for section name */ + for (h = cfg; h != NULL; h = h->next) { + if (strcmp(section, h->section) == 0) { + /* Search for key within section */ + for (e = h->entries; e != NULL; e = e->next) { + if (strcmp(key, e->key) == 0) { + /* Found! */ + return e->value; + } + } + } + } + /* Key not found in section */ + return NULL; +} + +/* Set the value of a key in a config file. Return the new value if + the section/key can be found, else return NULL. */ + +char *CFG_Set(struct CFG_Header *cfg, char *section, char *key, + char *value) +{ + struct CFG_Header *h; + struct CFG_Entry *e; + + if ((cfg == NULL) || (section == NULL) || (key == NULL) || + (value == NULL)) { + return NULL; + } + + /* Search for section name */ + for (h = cfg; h != NULL; h = h->next) { + if (strcmp(section, h->section) == 0) { + /* Search for key within section */ + for (e = h->entries; e != NULL; e = e->next) { + if ((e->key != NULL) && strcmp(key, e->key) == 0) { + /* Found - set value */ + free(e->key); + /* FIXME: strdup is not ANSI C compliant. */ + e->key = strdup(value); + return e->value; + } + } + } + } + /* Key not found in section */ + return NULL; +} + +struct CFG_Header *CFG_FindGnokiirc() +{ + struct CFG_Header *cfg_info; + char *homedir; + char rcfile[200]; + +#ifdef WIN32 + homedir = getenv("HOMEDRIVE"); + strncpy(rcfile, homedir ? homedir : "", 200); + homedir = getenv("HOMEPATH"); + strncat(rcfile, homedir ? homedir : "", 200); + strncat(rcfile, "\gnokiirc", 200); +#else + homedir = getenv("HOME"); + if (homedir) strncpy(rcfile, homedir, 200); + strncat(rcfile, "/.gnokiirc", 200); +#endif + + /* Try opening .gnokirc from users home directory first */ + if ((cfg_info = CFG_ReadFile(rcfile)) == NULL) { +#ifndef WIN32 + + /* It failed so try for /etc/gnokiirc */ + if ((cfg_info = CFG_ReadFile("/etc/gnokiirc")) == NULL) { + /* That failed too so exit */ +#ifdef DEBUG + fprintf(stderr, _("Couldn't open %s or /etc/gnokiirc. Using defaults...\n"), rcfile); +#endif /* DEBUG */ + return NULL; + } + +#else /* WIN32 */ + + /* It failed so try for gnokiirc */ + if ((cfg_info = CFG_ReadFile("gnokiirc")) == NULL) { + /* That failed too so exit */ +#ifdef DEBUG + fprintf(stderr, _("Couldn't open %s or gnokiirc. Using defaults...\n"), rcfile); +#endif /* DEBUG */ + return NULL; + } + +#endif /* WIN32 */ + } + + return cfg_info; +} + +int CFG_ReadConfig(char **model, char **port, char **initlength, + char **connection, char **bindir, char **synchronizetime, + bool isgnokiid) +{ + struct CFG_Header *cfg_info; +#ifdef WIN32 + char *DefaultPort = "com2:"; +#else + char *DefaultPort = "/dev/ttyS1"; +#endif + char *DefaultModel = "auto"; + char *DefaultConnection = "fbus"; + char *DefaultBindir = "/usr/local/sbin/"; + char *DefaultSynchronizeTime = "yes"; + char *DefaultInitLength = "30"; + + char *section = "global"; + + (char *)*model = DefaultModel; + (char *)*port = DefaultPort; + (char *)*connection = DefaultConnection; + (char *)*bindir = DefaultBindir; + (char *)*synchronizetime = DefaultSynchronizeTime; + (char *)*initlength = DefaultInitLength; + + cfg_info=CFG_FindGnokiirc(); + if (cfg_info==NULL) return 0; + + if (isgnokiid) (char *)section = "gnokiid"; + + (char *)*model = CFG_Get(cfg_info, section, "model"); + if (!*model) (char *)*model = DefaultModel; + + (char *)*port = CFG_Get(cfg_info, section, "port"); + if (!*port) (char *)*port = DefaultPort; + + (char *)*connection = CFG_Get(cfg_info, section, "connection"); + if (!*connection) (char *)*connection = DefaultConnection; + + (char *)*bindir = CFG_Get(cfg_info, section, "bindir"); + if (!*bindir) (char *)*bindir = DefaultBindir; + + (char *)*synchronizetime = CFG_Get(cfg_info, section, "synchronizetime"); + if (!*synchronizetime) (char *)*synchronizetime = DefaultSynchronizeTime; + + (char *)*initlength = CFG_Get(cfg_info, section, "initlength"); + if (!*initlength) (char *)*initlength = "default"; + + return 0; +}