1 // $Id: settings.c,v 1.2 2007-03-28 04:33:41 quinn Exp $
2 // This module implements a generic system of settings (attribute-value) that can
3 // be associated with search targets. The system supports both default values,
4 // per-target overrides, and per-user settings.
14 #include <libxml/parser.h>
15 #include <libxml/tree.h>
22 #define PZ_PIGGYBACK 0
26 static char *hard_settings[] = {
41 struct setting_dictionary
48 static int isdir(const char *path)
52 if (stat(path, &st) < 0)
54 yaz_log(YLOG_FATAL|YLOG_ERRNO, "%s", path);
57 return st.st_mode & S_IFDIR;
60 static void read_settings_file(const char *path, void *context,
61 void (*fun)(void *context, struct setting *set))
63 xmlDoc *doc = xmlParseFile(path);
65 //xmlChar *namea, *targeta, *valuea, *usera;
69 yaz_log(YLOG_FATAL, "Failed to parse %s", path);
72 n = xmlDocGetRootElement(doc);
74 for (n = n->children; n; n = n->next)
76 fprintf(stderr, "Node name: %s\n", n->name);
80 // Recursively read files in a directory structure, calling
81 static void read_settings(const char *path, void *context,
82 void (*fun)(void *context, struct setting *set))
87 if (!(d = opendir(path)))
89 yaz_log(YLOG_FATAL|YLOG_ERRNO, "%s", path);
92 while ((de = readdir(d)))
95 if (*de->d_name == '.' || !strcmp(de->d_name, "CVS"))
97 sprintf(tmp, "%s/%s", path, de->d_name);
99 read_settings(tmp, context, fun);
103 if ((dot = rindex(de->d_name, '.')) && !strcmp(dot + 1, "xml"))
104 read_settings_file(tmp, context, fun);
110 // Callback. Adds a new entry to the dictionary if necessary
111 // This is used in pass 1 to determine layout of dictionary
112 static void prepare_dictionary(void *context, struct setting *set)
114 struct setting_dictionary *dict = (struct setting_dictionary *) context;
117 for (i = 0; i < dict->num; i++)
118 if (!strcmp(set->name, set->name))
120 // Create a new dictionary entry
121 // Grow dictionary if necessary
123 dict->dict = nmem_malloc(nmem, (dict->size = 50) * sizeof(char*));
124 else if (dict->num + 1 > dict->size)
126 char **tmp = nmem_malloc(nmem, dict->size * 2 * sizeof(char*));
127 memcpy(tmp, dict->dict, dict->size * sizeof(char*));
131 dict->dict[dict->num++] = nmem_strdup(nmem, set->name);
135 // Callback -- updates database records with dictionary entries as appropriate
136 static void update_databases(void *context, struct setting *set)
141 // This simply copies the 'hard' (application-specific) settings
142 // to the settings dictionary.
143 static void initialize_hard_settings(struct setting_dictionary *dict)
145 dict->dict = nmem_malloc(nmem, sizeof(hard_settings) - sizeof(char*));
146 dict->size = (sizeof(hard_settings) - sizeof(char*)) / sizeof(char*);
147 memcpy(dict->dict, hard_settings, dict->size * sizeof(char*));
148 dict->num = dict->size;
151 // If we ever decide we need to be able to specify multiple settings directories,
152 // the two calls to read_settings must be split -- so the dictionary is prepared
153 // for the contents of every directory before the databases are updated.
154 void settings_read(const char *path)
156 struct setting_dictionary *new;
158 nmem = nmem_create();
161 new = nmem_malloc(nmem, sizeof(*new));
162 initialize_hard_settings(new);
163 memset(new, sizeof(*new), 0);
164 read_settings(path, new, prepare_dictionary);
165 //read_settings(path, new, update_databases);
171 * indent-tabs-mode: nil
173 * vim: shiftwidth=4 tabstop=8 expandtab