+ xfree(val_buf);
+ fclose(fr);
+ return ZEBRA_OK;
+}
+Res res_open(Res def_res, Res over_res)
+{
+ Res r;
+ r = (Res) xmalloc(sizeof(*r));
+ r->first = r->last = NULL;
+ r->def_res = def_res;
+ r->over_res = over_res;
+ return r;
+}
+
+void res_clear(Res r)
+{
+ struct res_entry *re, *re1;
+ for (re = r->first; re; re=re1)
+ {
+ if (re->name)
+ xfree(re->name);
+ if (re->value)
+ xfree(re->value);
+ re1 = re->next;
+ xfree(re);
+ }
+ r->first = r->last = NULL;
+}
+
+void res_close(Res r)
+{
+ if (!r)
+ return;
+ res_clear(r);
+
+ xfree(r);
+}
+
+const char *res_get_prefix(Res r, const char *name, const char *prefix,
+ const char *def)
+{
+ const char *v = 0;;
+ if (prefix)
+ {
+ char rname[128];
+
+ if (strlen(name) + strlen(prefix) >= (sizeof(rname)-2))
+ return 0;
+ strcpy(rname, prefix);
+ strcat(rname, ".");
+ strcat(rname, name);
+ v = res_get(r, rname);
+ }
+ if (!v)
+ v = res_get(r, name);
+ if (!v)
+ v = def;
+ return v;
+}
+
+const char *res_get(Res r, const char *name)
+{
+ struct res_entry *re;
+ const char *v;
+
+ if (!r)
+ return 0;
+
+ v = res_get(r->over_res, name);
+ if (v)
+ return v;
+
+ for (re = r->first; re; re=re->next)
+ if (re->value && !yaz_matchstr(re->name, name))
+ return re->value;
+
+ return res_get(r->def_res, name);
+}
+
+const char *res_get_def(Res r, const char *name, const char *def)
+{
+ const char *t;
+
+ if (!(t = res_get(r, name)))
+ {
+ yaz_log(YLOG_DEBUG, "CAUTION: Using default resource %s:%s", name, def);
+ return def;
+ }
+ else
+ return t;