+int Yaz_ProxyConfig::atoi_l(const char **cp)
+{
+ int v = 0;
+ while (**cp && isdigit(**cp))
+ {
+ v = v*10 + (**cp - '0');
+ (*cp)++;
+ }
+ return v;
+}
+
+int Yaz_ProxyConfig::match_list(int v, const char *m)
+{
+ while(m && *m)
+ {
+ while(*m && isspace(*m))
+ m++;
+ if (*m == '*')
+ return 1;
+ int l = atoi_l(&m);
+ int h = l;
+ if (*m == '-')
+ {
+ ++m;
+ h = atoi_l(&m);
+ }
+ if (v >= l && v <= h)
+ return 1;
+ if (*m == ',')
+ m++;
+ }
+ return 0;
+}
+
+#if HAVE_XML2
+int Yaz_ProxyConfig::check_type_1_attributes(ODR odr, xmlNodePtr ptrl,
+ Z_AttributeList *attrs,
+ char **addinfo)
+{
+ int i;
+ for (i = 0; i<attrs->num_attributes; i++)
+ {
+ Z_AttributeElement *el = attrs->attributes[i];
+
+ if (!el->attributeType)
+ continue;
+ int type = *el->attributeType;
+ int *value = 0;
+
+ if (el->which == Z_AttributeValue_numeric && el->value.numeric)
+ value = el->value.numeric;
+
+ xmlNodePtr ptr;
+ for(ptr = ptrl->children; ptr; ptr = ptr->next)
+ {
+ if (ptr->type == XML_ELEMENT_NODE &&
+ !strcmp((const char *) ptr->name, "attribute"))
+ {
+ const char *match_type = 0;
+ const char *match_value = 0;
+ const char *match_error = 0;
+ struct _xmlAttr *attr;
+ for (attr = ptr->properties; attr; attr = attr->next)
+ {
+ if (!strcmp((const char *) attr->name, "type") &&
+ attr->children && attr->children->type == XML_TEXT_NODE)
+ match_type = (const char *) attr->children->content;
+ if (!strcmp((const char *) attr->name, "value") &&
+ attr->children && attr->children->type == XML_TEXT_NODE)
+ match_value = (const char *) attr->children->content;
+ if (!strcmp((const char *) attr->name, "error") &&
+ attr->children && attr->children->type == XML_TEXT_NODE)
+ match_error = (const char *) attr->children->content;
+ }
+ if (match_type && match_value)
+ {
+ char addinfo_str[20];
+ if (!match_list(type, match_type))
+ continue;
+
+ *addinfo_str = '\0';
+ if (!strcmp(match_type, "*"))
+ sprintf (addinfo_str, "%d", type);
+ else if (value)
+ {
+ if (!match_list(*value, match_value))
+ continue;
+ sprintf (addinfo_str, "%d", *value);
+ }
+ else
+ continue;
+
+ if (match_error)
+ {
+ if (*addinfo_str)
+ *addinfo = odr_strdup(odr, addinfo_str);
+ return atoi(match_error);
+ }
+ return 0;
+ }
+ }
+ }
+ }
+ return 0;
+}
+#endif
+
+#if HAVE_XML2
+int Yaz_ProxyConfig::check_type_1_structure(ODR odr, xmlNodePtr ptr,
+ Z_RPNStructure *q,
+ char **addinfo)
+{
+ if (q->which == Z_RPNStructure_complex)
+ {
+ int e = check_type_1_structure(odr, ptr, q->u.complex->s1, addinfo);
+ if (e)
+ return e;
+ e = check_type_1_structure(odr, ptr, q->u.complex->s2, addinfo);
+ return e;
+ }
+ else if (q->which == Z_RPNStructure_simple)
+ {
+ if (q->u.simple->which == Z_Operand_APT)
+ {
+ return check_type_1_attributes(
+ odr, ptr, q->u.simple->u.attributesPlusTerm->attributes,
+ addinfo);
+ }
+ }
+ return 0;
+}
+#endif
+
+#if HAVE_XML2
+int Yaz_ProxyConfig::check_type_1(ODR odr, xmlNodePtr ptr, Z_RPNQuery *query,
+ char **addinfo)
+{
+ // possibly check for Bib-1
+ return check_type_1_structure(odr, ptr, query->RPNStructure, addinfo);
+}
+#endif
+
+int Yaz_ProxyConfig::check_query(ODR odr, const char *name, Z_Query *query,
+ char **addinfo)