X-Git-Url: http://lists.indexdata.com/cgi-bin?a=blobdiff_plain;ds=sidebyside;f=src%2Fsettings.c;h=72a47d0e0d8e4525148b6ebeb171b96cb9129e87;hb=85a3ecf154edbf4a0d7ca8b8d4e72c2e94d00a6d;hp=44de854d29e1beb52544872b1f4f114cb8ee6ed5;hpb=216073a7a0d2fdfc9d88c58b1a2ff83fa76d4628;p=pazpar2-moved-to-github.git diff --git a/src/settings.c b/src/settings.c index 44de854..72a47d0 100644 --- a/src/settings.c +++ b/src/settings.c @@ -65,6 +65,8 @@ static char *hard_settings[] = { "pz:sru", "pz:sru_version", "pz:pqf_prefix", + "pz:sort", + "pz:recordfilter", 0 }; @@ -132,21 +134,13 @@ static int isdir(const char *path) } // Read settings from an XML file, calling handler function for each setting -static void read_settings_file(const char *path, - struct conf_service *service, - void (*fun)(struct conf_service *service, - struct setting *set)) +void settings_read_node_x(xmlNode *n, + void *client_data, + void (*fun)(void *client_data, + struct setting *set)) { - xmlDoc *doc = xmlParseFile(path); - xmlNode *n; xmlChar *namea, *targeta, *valuea, *usera, *precedencea; - if (!doc) - { - yaz_log(YLOG_FATAL, "Failed to parse %s", path); - exit(1); - } - n = xmlDocGetRootElement(doc); namea = xmlGetProp(n, (xmlChar *) "name"); targeta = xmlGetProp(n, (xmlChar *) "target"); valuea = xmlGetProp(n, (xmlChar *) "value"); @@ -202,7 +196,7 @@ static void read_settings_file(const char *path, strcpy(valueb, (const char *) valuea); set.value = valueb; set.next = 0; - (*fun)(service, &set); + (*fun)(client_data, &set); } xmlFree(name); xmlFree(precedence); @@ -221,15 +215,33 @@ static void read_settings_file(const char *path, xmlFree(valuea); xmlFree(usera); xmlFree(targeta); +} + +static void read_settings_file(const char *path, + void *client_data, + void (*fun)(void *client_data, + struct setting *set)) +{ + xmlDoc *doc = xmlParseFile(path); + xmlNode *n; + + if (!doc) + { + yaz_log(YLOG_FATAL, "Failed to parse %s", path); + exit(1); + } + n = xmlDocGetRootElement(doc); + settings_read_node_x(n, client_data, fun); xmlFreeDoc(doc); } - + + // Recursively read files or directories, invoking a // callback for each one static void read_settings(const char *path, - struct conf_service *service, - void (*fun)(struct conf_service *service, + void *client_data, + void (*fun)(void *client_data, struct setting *set)) { DIR *d; @@ -249,12 +261,12 @@ static void read_settings(const char *path, if (*de->d_name == '.' || !strcmp(de->d_name, "CVS")) continue; sprintf(tmp, "%s/%s", path, de->d_name); - read_settings(tmp, service, fun); + read_settings(tmp, client_data, fun); } closedir(d); } else if ((dot = strrchr(path, '.')) && !strcmp(dot + 1, "xml")) - read_settings_file(path, service, fun); + read_settings_file(path, client_data, fun); } // Determines if a ZURL is a wildcard, and what kind @@ -281,10 +293,6 @@ static void prepare_dictionary(struct conf_service *service, int i; char *p; - // If target address is not wildcard, add the database - if (*set->target && !zurl_wildcard(set->target)) - find_database(set->target, 0, service); - // Determine if we already have a dictionary entry if (!strncmp(set->name, "pz:", 3) && (p = strchr(set->name + 3, ':'))) *(p + 1) = '\0'; @@ -328,7 +336,7 @@ static void update_database(void *context, struct database *db) context)->set; struct conf_service *service = ((struct update_database_context *) context)->service; - struct setting *s, **sp; + struct setting **sp; int offset; // Is this the right database? @@ -340,24 +348,34 @@ static void update_database(void *context, struct database *db) // First we determine if this setting is overriding any existing settings // with the same name. - for (s = db->settings[offset], sp = &db->settings[offset]; s; - sp = &s->next, s = s->next) - if (!strcmp(s->name, set->name)) + assert(offset < db->num_settings); + for (sp = &db->settings[offset]; *sp; ) + if (!strcmp((*sp)->name, set->name)) { - if (s->precedence < set->precedence) + if ((*sp)->precedence < set->precedence) + { // We discard the value (nmem keeps track of the space) *sp = (*sp)->next; // unlink value from existing setting - else if (s->precedence > set->precedence) + } + else if ((*sp)->precedence > set->precedence) + { // Db contains a higher-priority setting. Abort search break; - if (zurl_wildcard(s->target) > zurl_wildcard(set->target)) + } + else if (zurl_wildcard((*sp)->target) > zurl_wildcard(set->target)) + { // target-specific value trumps wildcard. Delete. *sp = (*sp)->next; // unlink..... - else if (!zurl_wildcard(s->target)) + } + else if (!zurl_wildcard((*sp)->target)) // Db already contains higher-priority setting. Abort search break; + else + sp = &(*sp)->next; } - if (!s) // s will be null when there are no higher-priority settings -- we add one + else + sp = &(*sp)->next; + if (!*sp) // is null when there are no higher-priority settings, so we add one { struct setting *new = nmem_malloc(service->nmem, sizeof(*new)); @@ -373,9 +391,9 @@ static void update_database(void *context, struct database *db) // Callback -- updates database records with dictionary entries as appropriate // This is used in pass 2 to assign name/value pairs to databases -static void update_databases(struct conf_service *service, - struct setting *set) +static void update_databases(void *client_data, struct setting *set) { + struct conf_service *service = (struct conf_service *) client_data; struct update_database_context context; context.set = set; context.service = service; @@ -416,9 +434,9 @@ static void initialize_soft_settings(struct conf_service *service) } } -static void prepare_target_dictionary(struct conf_service *service, - struct setting *set) +static void prepare_target_dictionary(void *client_data, struct setting *set) { + struct conf_service *service = (struct conf_service *) client_data; struct setting_dictionary *dictionary = service->dictionary; int i; @@ -434,24 +452,15 @@ static void prepare_target_dictionary(struct conf_service *service, for (i = 0; i < dictionary->num; i++) if (!strcmp(dictionary->dict[i], set->name)) return; - yaz_log(YLOG_WARN, "setting %s not configured as metadata", set->name); -} - -// If we ever decide we need to be able to specify multiple settings directories, -// the two calls to read_settings must be split -- so the dictionary is prepared -// for the contents of every directory before the databases are updated. -void settings_read(struct conf_service *service, const char *path) -{ - read_settings(path, service, prepare_target_dictionary); - read_settings(path, service, update_databases); + yaz_log(YLOG_WARN, "Setting '%s' not configured as metadata", set->name); } void init_settings(struct conf_service *service) { struct setting_dictionary *new; - + assert(service->nmem); - + new = nmem_malloc(service->nmem, sizeof(*new)); memset(new, 0, sizeof(*new)); service->dictionary = new; @@ -459,6 +468,24 @@ void init_settings(struct conf_service *service) initialize_soft_settings(service); } +void settings_read_file(struct conf_service *service, const char *path, + int pass) +{ + if (pass == 1) + read_settings(path, service, prepare_target_dictionary); + else + read_settings(path, service, update_databases); +} + +void settings_read_node(struct conf_service *service, xmlNode *n, + int pass) +{ + if (pass == 1) + settings_read_node_x(n, service, prepare_target_dictionary); + else + settings_read_node_x(n, service, update_databases); +} + /* * Local variables: * c-basic-offset: 4