X-Git-Url: http://git.indexdata.com/?p=idzebra-moved-to-github.git;a=blobdiff_plain;f=util%2Fres.c;h=efb6473806a4dc26c503fee9d13c204e9566f855;hp=4e26a7a66d7d2fff8669011d804803b36d10bc2e;hb=96e4c5479e111511f5df3531b6648931251b9e5d;hpb=58e601f9b6d9ac15b90fa7c72686e81e01e5416f diff --git a/util/res.c b/util/res.c index 4e26a7a..efb6473 100644 --- a/util/res.c +++ b/util/res.c @@ -1,8 +1,5 @@ -/* $Id: res.c,v 1.47 2005-10-27 08:49:29 adam Exp $ - Copyright (C) 1995-2005 - Index Data ApS - -This file is part of the Zebra server. +/* This file is part of the Zebra server. + Copyright (C) 1994-2011 Index Data Zebra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -15,11 +12,14 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with Zebra; see the file LICENSE.zebra. If not, write to the -Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#if HAVE_CONFIG_H +#include +#endif #include #include #include @@ -31,6 +31,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #endif +#include #include #include @@ -43,11 +44,19 @@ struct res_entry { }; struct res_struct { + int ref_count; struct res_entry *first, *last; Res def_res; Res over_res; }; +static Res res_incref(Res r) +{ + if (r) + r->ref_count++; + return r; +} + static struct res_entry *add_entry(Res r) { struct res_entry *resp; @@ -136,12 +145,8 @@ static char *xstrdup_env(const char *src) ZEBRA_RES res_read_file(Res r, const char *fname) { - struct res_entry *resp; - char *line; - char *val_buf; - int val_size, val_max = 256; - char fr_buf[1024]; FILE *fr; + int errors = 0; assert(r); @@ -149,90 +154,92 @@ ZEBRA_RES res_read_file(Res r, const char *fname) if (!fr) { yaz_log(YLOG_WARN|YLOG_ERRNO, "Cannot open `%s'", fname); - return ZEBRA_FAIL; + errors++; } - val_buf = (char*) xmalloc(val_max); - while (1) + else { - line = fgets(fr_buf, sizeof(fr_buf)-1, fr); - if (!line) - break; - if (*line != '#') + char fr_buf[1024]; + char *line; + int lineno = 1; + WRBUF wrbuf_val = wrbuf_alloc(); + yaz_tok_cfg_t yt = yaz_tok_cfg_create(); + + while ((line = fgets(fr_buf, sizeof(fr_buf)-1, fr))) { - int no = 0; - while (1) + yaz_tok_parse_t tp = yaz_tok_parse_buf(yt, line); + int t = yaz_tok_move(tp); + + if (t == YAZ_TOK_STRING) { - if (fr_buf[no] == 0 || fr_buf[no] == '\n' ) + size_t sz; + struct res_entry *resp; + const char *cp = yaz_tok_parse_string(tp); + const char *cp1 = strchr(cp, ':'); + + if (!cp1) { - no = 0; + yaz_log(YLOG_FATAL, "%s:%d missing colon after '%s'", + fname, lineno, cp); + errors++; break; } - if (strchr(": \t", fr_buf[no])) - break; - no++; - } - if (!no) - continue; - fr_buf[no++] = '\0'; - resp = add_entry(r); - resp->name = (char*) xmalloc(no); - strcpy(resp->name, fr_buf); - - while (strchr(" \t", fr_buf[no])) - no++; - val_size = 0; - while (1) - { - if (fr_buf[no] == '\0' || strchr("\n\r\f", fr_buf[no])) + resp = add_entry(r); + sz = cp1 - cp; + resp->name = xmalloc(sz + 1); + memcpy(resp->name, cp, sz); + resp->name[sz] = '\0'; + + wrbuf_rewind(wrbuf_val); + + if (cp1[1]) { - while (val_size > 0 && - (val_buf[val_size-1] == ' ' || - val_buf[val_size-1] == '\t')) - val_size--; - val_buf[val_size] = '\0'; - resp->value = xstrdup_env(val_buf); - yaz_log(YLOG_DEBUG, "(name=%s,value=%s)", - resp->name, resp->value); - break; + /* name:value */ + wrbuf_puts(wrbuf_val, cp1+1); } - else if (fr_buf[no] == '\\' && strchr("\n\r\f", fr_buf[no+1])) + else { - line = fgets(fr_buf, sizeof(fr_buf)-1, fr); - if (!line) + /* name: value */ + t = yaz_tok_move(tp); + + if (t != YAZ_TOK_STRING) { - val_buf[val_size] = '\0'; - resp->value = xstrdup_env(val_buf); + resp->value = xstrdup(""); + yaz_log(YLOG_FATAL, "%s:%d missing value after '%s'", + fname, lineno, resp->name); + errors++; break; } - no = 0; + wrbuf_puts(wrbuf_val, yaz_tok_parse_string(tp)); } - else + while ((t=yaz_tok_move(tp)) == YAZ_TOK_STRING) { - val_buf[val_size++] = fr_buf[no++]; - if (val_size+1 >= val_max) - { - char *nb; - - nb = (char*) xmalloc(val_max+=1024); - memcpy(nb, val_buf, val_size); - xfree(val_buf); - val_buf = nb; - } + wrbuf_putc(wrbuf_val, ' '); + wrbuf_puts(wrbuf_val, yaz_tok_parse_string(tp)); } + resp->value = xstrdup_env(wrbuf_cstr(wrbuf_val)); + /* printf("name=%s value=%s\n", resp->name, resp->value); */ } - } - } - xfree(val_buf); - fclose(fr); + lineno++; + yaz_tok_parse_destroy(tp); + } + fclose(fr); + yaz_tok_cfg_destroy(yt); + wrbuf_destroy(wrbuf_val); + } + if (errors) + return ZEBRA_FAIL; return ZEBRA_OK; } + Res res_open(Res def_res, Res over_res) { Res r; r = (Res) xmalloc(sizeof(*r)); + + r->ref_count = 1; r->first = r->last = NULL; - r->def_res = def_res; - r->over_res = over_res; + r->def_res = res_incref(def_res); + r->over_res = res_incref(over_res); return r; } @@ -253,11 +260,13 @@ void res_clear(Res r) void res_close(Res r) { - if (!r) - return; - res_clear(r); - - xfree(r); + if (r && --(r->ref_count) == 0) + { + res_clear(r); + res_close(r->def_res); + res_close(r->over_res); + xfree(r); + } } const char *res_get_prefix(Res r, const char *name, const char *prefix, @@ -307,7 +316,8 @@ const char *res_get_def(Res r, const char *name, const char *def) if (!(t = res_get(r, name))) { - yaz_log(YLOG_DEBUG, "CAUTION: Using default resource %s:%s", name, def); + if (def) + yaz_log(YLOG_DEBUG, "Using default resource %s:%s", name, def); return def; } else @@ -330,6 +340,8 @@ void res_set(Res r, const char *name, const char *value) struct res_entry *re; assert(r); + if (!value) + return; for (re = r->first; re; re=re->next) if (re->value && !yaz_matchstr(re->name, name)) { @@ -343,7 +355,7 @@ void res_set(Res r, const char *name, const char *value) } int res_trav(Res r, const char *prefix, void *p, - void (*f)(void *p, const char *name, const char *value)) + void (*f)(void *p, const char *name, const char *value)) { struct res_entry *re; int l = 0; @@ -379,7 +391,7 @@ ZEBRA_RES res_write_file(Res r, const char *fname) if (!fr) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "Cannot create `%s'", fname); - exit(1); + return ZEBRA_FAIL; } for (re = r->first; re; re=re->next) @@ -429,97 +441,20 @@ ZEBRA_RES res_get_int(Res r, const char *name, int *val) return ZEBRA_FAIL; } -/* == pop ================================================================= */ -Res res_add_over (Res p, Res t) -{ - if ((!p) || (!t)) - return (0); - - while (p->over_res) - p = p->over_res; - - p->over_res = t; - return (p); -} - -void res_remove_over (Res r) -{ - if (!r) - return; - r->over_res = 0; -} - -void res_close_over (Res r) -{ - if (!r) - return; - if (r->over_res) - res_close(r->over_res); - r->over_res = 0; -} - -void res_add (Res r, const char *name, const char *value) -{ - struct res_entry *re; - assert (r); - if ((name) && (value)) - yaz_log (YLOG_RES, "res_add res=%p, name=%s, value=%s", r, name, value); - - re = add_entry (r); - re->name = xstrdup (name); - re->value = xstrdup_env (value); -} - -char **res_2_array (Res r) -{ - struct res_entry *re; - int i = 0; - char **list; - - if (!r) - return 0; - - list = xmalloc(sizeof(char *)); - - for (re = r->first; re; re=re->next) { - list = xrealloc(list, ((i+3) * sizeof(char *))); - list[i++] = strdup(re->name); - if (re->value) - list[i++] = strdup(re->value); - else - list[i++] = strdup(""); - yaz_log(YLOG_RES, "res2array: %s=%s",re->name, re->value); - } - list[i++] = 0; - return (list); -} -char **res_get_array(Res r, const char* name) +void res_add(Res r, const char *name, const char *value) { struct res_entry *re; - int i = 0; - char **list; - - if (!r) - return 0; - - list = xmalloc(sizeof(char *)); - - for (re = r->first; re; re=re->next) - if (re->value && !yaz_matchstr (re->name, name)) - { - list = xrealloc(list, (i+2) * sizeof(char *)); - list[i++] = xstrdup(re->value); - } - - if (i == 0) - return (res_get_array(r->def_res, name)); - - list[i++] = 0; - return (list); + assert(r); + assert(name); + assert(value); + yaz_log(YLOG_RES, "res_add res=%p, name=%s, value=%s", r, name, value); + re = add_entry(r); + re->name = xstrdup(name); + re->value = xstrdup_env(value); } -void res_dump (Res r, int level) +void res_dump(Res r, int level) { struct res_entry *re; @@ -531,12 +466,87 @@ void res_dump (Res r, int level) } if (r->def_res) { - printf ("%*s DEF ",level * 4,""); - res_dump (r->def_res, level + 1); + printf("%*s DEF ",level * 4,""); + res_dump(r->def_res, level + 1); } if (r->over_res) { - printf ("%*s OVER ",level * 4,""); - res_dump (r->over_res, level + 1); + printf("%*s OVER ",level * 4,""); + res_dump(r->over_res, level + 1); } } + +int res_check(Res r_i, Res r_v) +{ + struct res_entry *e_i; + int errors = 0; + + for (e_i = r_i->first; e_i; e_i = e_i->next) + { + struct res_entry *e_v; + for (e_v = r_v->first; e_v; e_v = e_v->next) + { + int prefix_allowed = 0; + int suffix_allowed = 0; + const char *name = e_i->name; + size_t name_len = strlen(e_i->name); + char namez[32]; + const char *first_dot = 0; + const char *second_dot = 0; + + if (strchr(e_v->value, 'p')) + prefix_allowed = 1; + if (strchr(e_v->value, 's')) + suffix_allowed = 1; + + first_dot = strchr(name, '.'); + if (prefix_allowed && first_dot) + { + name = first_dot+1; + name_len = strlen(name); + } + second_dot = strchr(name, '.'); + if (suffix_allowed && second_dot) + { + name_len = second_dot - name; + } + if (name_len < sizeof(namez)-1) + { + memcpy(namez, name, name_len); + namez[name_len] = '\0'; + if (!yaz_matchstr(namez, e_v->name)) + break; + } + /* for case 'a.b' we have to check 'a' as well */ + if (prefix_allowed && suffix_allowed && first_dot && !second_dot) + { + name = e_i->name; + name_len = first_dot - name; + if (name_len < sizeof(namez)-1) + { + memcpy(namez, name, name_len); + namez[name_len] = '\0'; + if (!yaz_matchstr(namez, e_v->name)) + break; + } + } + } + if (!e_v) + { + yaz_log(YLOG_WARN, "The following setting is unrecognized: %s", + e_i->name); + errors++; + } + } + return errors; +} + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ +