/* $Id: conf.c,v 1.3 2004/03/26 02:19:03 jmuelmen Exp $ */ /* This file reads the global ambush configuration file (~/.ambush/config) */ #include #include #include #include #include "conf.h" #include "conf_int.h" #define NC 1024 static struct conf_ent _conf_table[NC] = { { "TURBODAQ_DIR", "/cygdrive/c/TurboDAQ_files" }, { "RANDOM_VALUE", "foo_bar" } }; static int _nc = 2; static pthread_mutex_t _mut; static int ct_lock () { int ret = pthread_mutex_lock(&_mut); if (ret) perror("Locking config table mutex"); return ret; } static int ct_unlock () { int ret = pthread_mutex_unlock(&_mut); if (ret) perror("Unlocking config table mutex"); return ret; } static FILE *get_conf_file () { /* this function wants to be called when you've acquired the lock already. */ char home_dir[STRLEN]; char fname[STRLEN]; FILE *ret; strncpy(home_dir, getenv("HOME"), STRLEN - 1); home_dir[STRLEN - 1] = 0; snprintf(fname, STRLEN, "%s/.ambush/config", home_dir); fname[STRLEN - 1] = 0; if (!(ret = fopen(fname, "r"))) perror("Opening configuration file"); return ret; } static void conf_sort (); static int conf_table_init () { int ret; conf_sort(); if (ret = pthread_mutex_init(&_mut, NULL)) perror("Initializing configuration table mutex"); return ret; } int load_config () { int i; FILE *conf_file; conf_table_init(); if (!(conf_file = get_conf_file())) { /* live with the defaults... */ return -1; } conf_set_input(conf_file); conf_yyparse(); for (i = 0; i < _nc; ++i) printf("%s = %s\n", _conf_table[i].name, _conf_table[i].val); return 0; } /* This routine compares a string (k) to a conf var name */ static int conf_compar_search (const void *k, const void *c) { const char *key = (const char *)k; const struct conf_ent *conf = (const struct conf_ent *)c; return strncmp(key, conf->name, STRLEN); } /* This routine compares two struct mod_tbl_ent *s; it does so by comparing the modules names of each struct mod_tbl_ent *. It's only used by qsort to tidy up the list of modules. */ static int conf_compar_sort (const void *a, const void *b) { const struct conf_ent *c1 = (const struct conf_ent *)a; const struct conf_ent *c2 = (const struct conf_ent *)b; return strncmp(c1->name, c2->name, STRLEN); } static struct conf_ent *conf_search (const char *key) { /* this function is called by locking functions */ struct conf_ent *ret; ret = bsearch(key, _conf_table, _nc, sizeof(struct conf_ent), conf_compar_search); return ret; } static void conf_sort () { qsort(_conf_table, _nc, sizeof(struct conf_ent), conf_compar_sort); } static struct conf_ent *conf_add (const char *name, const char *val) { if (_nc == NC) { fprintf(stderr, "No space in config table\n"); return NULL; } strncpy(_conf_table[_nc].name, name, STRLEN); strncpy(_conf_table[_nc].val, val, STRLEN); return &_conf_table[_nc++]; } int conf_set (const char *name, const char *val) { struct conf_ent *c; ct_lock(); if (c = conf_search(name)) { strncpy(c->val, val, STRLEN); ct_unlock(); return 0; } if (!(c = conf_add(name, val))) { ct_unlock(); return -1; } conf_sort(); ct_unlock(); return 0; } int conf_get (const char *name, char *val, int size) { struct conf_ent *c; ct_lock(); if (c = conf_search(name)) { strncpy(val, c->val, size); } ct_unlock(); return (c == NULL); }