2 * Copyright (c) 1998-2003, Index Data.
3 * See the file LICENSE for details.
5 * $Id: yaz-proxy-config.cpp,v 1.16 2003-12-20 22:44:30 adam Exp $
10 #include <yaz++/proxy.h>
12 Yaz_ProxyConfig::Yaz_ProxyConfig()
21 Yaz_ProxyConfig::~Yaz_ProxyConfig()
24 if (!m_copy && m_docPtr)
29 int Yaz_ProxyConfig::read_xml(const char *fname)
32 xmlDocPtr ndoc = xmlParseFile(fname);
36 yaz_log(LOG_WARN, "Config file %s not found or parse error", fname);
39 xmlNodePtr proxyPtr = xmlDocGetRootElement(ndoc);
40 if (!proxyPtr || proxyPtr->type != XML_ELEMENT_NODE ||
41 strcmp((const char *) proxyPtr->name, "proxy"))
43 yaz_log(LOG_WARN, "No proxy element in %s", fname);
47 m_proxyPtr = proxyPtr;
49 // OK: release previous and make it the current one.
60 const char *Yaz_ProxyConfig::get_text(xmlNodePtr ptr)
62 for(ptr = ptr->children; ptr; ptr = ptr->next)
63 if (ptr->type == XML_TEXT_NODE)
65 xmlChar *t = ptr->content;
70 return (const char *) t;
78 void Yaz_ProxyConfig::return_limit(xmlNodePtr ptr,
83 for (ptr = ptr->children; ptr; ptr = ptr->next)
85 if (ptr->type == XML_ELEMENT_NODE
86 && !strcmp((const char *) ptr->name, "bandwidth"))
88 const char *t = get_text(ptr);
92 if (ptr->type == XML_ELEMENT_NODE
93 && !strcmp((const char *) ptr->name, "retrieve"))
95 const char *t = get_text(ptr);
99 if (ptr->type == XML_ELEMENT_NODE
100 && !strcmp((const char *) ptr->name, "pdu"))
102 const char *t = get_text(ptr);
104 *limit_pdu = atoi(t);
111 void Yaz_ProxyConfig::return_target_info(xmlNodePtr ptr,
116 int *target_idletime,
117 int *client_idletime,
118 int *keepalive_limit_bw,
119 int *keepalive_limit_pdu,
121 const char **cql2rpn,
127 for (; ptr; ptr = ptr->next)
129 if (ptr->type == XML_ELEMENT_NODE
130 && !strcmp((const char *) ptr->name, "preinit"))
132 const char *v = get_text(ptr);
133 *pre_init = v ? atoi(v) : 1;
135 if (ptr->type == XML_ELEMENT_NODE
136 && !strcmp((const char *) ptr->name, "url"))
138 const char *t = get_text(ptr);
139 if (t && no_url < MAX_ZURL_PLEX)
145 if (ptr->type == XML_ELEMENT_NODE
146 && !strcmp((const char *) ptr->name, "keepalive"))
149 *keepalive_limit_bw = 500000;
150 *keepalive_limit_pdu = 1000;
151 return_limit(ptr, keepalive_limit_bw, keepalive_limit_pdu,
154 if (ptr->type == XML_ELEMENT_NODE
155 && !strcmp((const char *) ptr->name, "limit"))
156 return_limit(ptr, limit_bw, limit_pdu, limit_req);
157 if (ptr->type == XML_ELEMENT_NODE
158 && !strcmp((const char *) ptr->name, "target-timeout"))
160 const char *t = get_text(ptr);
163 *target_idletime = atoi(t);
164 if (*target_idletime < 0)
165 *target_idletime = 0;
168 if (ptr->type == XML_ELEMENT_NODE
169 && !strcmp((const char *) ptr->name, "client-timeout"))
171 const char *t = get_text(ptr);
174 *client_idletime = atoi(t);
175 if (*client_idletime < 0)
176 *client_idletime = 0;
179 if (ptr->type == XML_ELEMENT_NODE
180 && !strcmp((const char *) ptr->name, "cql2rpn"))
182 const char *t = get_text(ptr);
186 if (ptr->type == XML_ELEMENT_NODE
187 && !strcmp((const char *) ptr->name, "zeerex"))
189 const char *t = get_text(ptr);
197 int Yaz_ProxyConfig::atoi_l(const char **cp)
200 while (**cp && isdigit(**cp))
202 v = v*10 + (**cp - '0');
208 int Yaz_ProxyConfig::match_list(int v, const char *m)
212 while(*m && isspace(*m))
223 if (v >= l && v <= h)
232 int Yaz_ProxyConfig::check_type_1_attributes(ODR odr, xmlNodePtr ptrl,
233 Z_AttributeList *attrs,
237 for (i = 0; i<attrs->num_attributes; i++)
239 Z_AttributeElement *el = attrs->attributes[i];
241 if (!el->attributeType)
243 int type = *el->attributeType;
246 if (el->which == Z_AttributeValue_numeric && el->value.numeric)
247 value = el->value.numeric;
250 for(ptr = ptrl->children; ptr; ptr = ptr->next)
252 if (ptr->type == XML_ELEMENT_NODE &&
253 !strcmp((const char *) ptr->name, "attribute"))
255 const char *match_type = 0;
256 const char *match_value = 0;
257 const char *match_error = 0;
258 struct _xmlAttr *attr;
259 for (attr = ptr->properties; attr; attr = attr->next)
261 if (!strcmp((const char *) attr->name, "type") &&
262 attr->children && attr->children->type == XML_TEXT_NODE)
263 match_type = (const char *) attr->children->content;
264 if (!strcmp((const char *) attr->name, "value") &&
265 attr->children && attr->children->type == XML_TEXT_NODE)
266 match_value = (const char *) attr->children->content;
267 if (!strcmp((const char *) attr->name, "error") &&
268 attr->children && attr->children->type == XML_TEXT_NODE)
269 match_error = (const char *) attr->children->content;
271 if (match_type && match_value)
273 char addinfo_str[20];
274 if (!match_list(type, match_type))
278 if (!strcmp(match_type, "*"))
279 sprintf (addinfo_str, "%d", type);
282 if (!match_list(*value, match_value))
284 sprintf (addinfo_str, "%d", *value);
292 *addinfo = odr_strdup(odr, addinfo_str);
293 return atoi(match_error);
305 int Yaz_ProxyConfig::check_type_1_structure(ODR odr, xmlNodePtr ptr,
309 if (q->which == Z_RPNStructure_complex)
311 int e = check_type_1_structure(odr, ptr, q->u.complex->s1, addinfo);
314 e = check_type_1_structure(odr, ptr, q->u.complex->s2, addinfo);
317 else if (q->which == Z_RPNStructure_simple)
319 if (q->u.simple->which == Z_Operand_APT)
321 return check_type_1_attributes(
322 odr, ptr, q->u.simple->u.attributesPlusTerm->attributes,
331 int Yaz_ProxyConfig::check_type_1(ODR odr, xmlNodePtr ptr, Z_RPNQuery *query,
334 // possibly check for Bib-1
335 return check_type_1_structure(odr, ptr, query->RPNStructure, addinfo);
339 int Yaz_ProxyConfig::check_query(ODR odr, const char *name, Z_Query *query,
345 ptr = find_target_node(name);
348 if (query->which == Z_Query_type_1 || query->which == Z_Query_type_101)
349 return check_type_1(odr, ptr, query->u.type_1, addinfo);
355 int Yaz_ProxyConfig::check_syntax(ODR odr, const char *name,
356 Odr_oid *syntax, char **addinfo)
361 ptr = find_target_node(name);
364 for(ptr = ptr->children; ptr; ptr = ptr->next)
366 if (ptr->type == XML_ELEMENT_NODE &&
367 !strcmp((const char *) ptr->name, "syntax"))
369 int match = 0; // if we match record syntax
370 const char *match_type = 0;
371 const char *match_error = 0;
372 const char *match_marcxml = 0;
373 struct _xmlAttr *attr;
374 for (attr = ptr->properties; attr; attr = attr->next)
376 if (!strcmp((const char *) attr->name, "type") &&
377 attr->children && attr->children->type == XML_TEXT_NODE)
378 match_type = (const char *) attr->children->content;
379 if (!strcmp((const char *) attr->name, "error") &&
380 attr->children && attr->children->type == XML_TEXT_NODE)
381 match_error = (const char *) attr->children->content;
382 if (!strcmp((const char *) attr->name, "marcxml") &&
383 attr->children && attr->children->type == XML_TEXT_NODE)
384 match_marcxml = (const char *) attr->children->content;
388 if (!strcmp(match_type, "*"))
390 else if (!strcmp(match_type, "none"))
397 int match_oid[OID_SIZE];
398 oid_name_to_oid(CLASS_RECSYN, match_type, match_oid);
399 if (oid_oidcmp(match_oid, syntax) == 0)
413 char dotoid_str[100];
414 oid_to_dotstring(syntax, dotoid_str);
415 *addinfo = odr_strdup(odr, dotoid_str);
417 return atoi(match_error);
428 xmlNodePtr Yaz_ProxyConfig::find_target_node(const char *name)
433 for (ptr = m_proxyPtr->children; ptr; ptr = ptr->next)
435 if (ptr->type == XML_ELEMENT_NODE &&
436 !strcmp((const char *) ptr->name, "target"))
441 // <target default="1"> ?
442 struct _xmlAttr *attr;
443 for (attr = ptr->properties; attr; attr = attr->next)
444 if (!strcmp((const char *) attr->name, "default") &&
445 attr->children && attr->children->type == XML_TEXT_NODE)
447 xmlChar *t = attr->children->content;
454 // <target name="name"> ?
455 struct _xmlAttr *attr;
456 for (attr = ptr->properties; attr; attr = attr->next)
457 if (!strcmp((const char *) attr->name, "name"))
460 && attr->children->type==XML_TEXT_NODE
461 && attr->children->content
462 && (!strcmp((const char *) attr->children->content,
464 || !strcmp((const char *) attr->children->content,
477 int Yaz_ProxyConfig::get_target_no(int no,
483 int *target_idletime,
484 int *client_idletime,
486 int *keepalive_limit_bw,
487 int *keepalive_limit_pdu,
489 const char **cql2rpn,
497 for (ptr = m_proxyPtr->children; ptr; ptr = ptr->next)
498 if (ptr->type == XML_ELEMENT_NODE &&
499 !strcmp((const char *) ptr->name, "target"))
503 struct _xmlAttr *attr;
504 for (attr = ptr->properties; attr; attr = attr->next)
505 if (!strcmp((const char *) attr->name, "name"))
508 && attr->children->type==XML_TEXT_NODE
509 && attr->children->content)
510 *name = (const char *) attr->children->content;
512 return_target_info(ptr, url, limit_bw, limit_pdu, limit_req,
513 target_idletime, client_idletime,
514 keepalive_limit_bw, keepalive_limit_pdu,
515 pre_init, cql2rpn, zeerex);
524 int Yaz_ProxyConfig::mycmp(const char *hay, const char *item, size_t len)
526 if (len == strlen(item) && memcmp(hay, item, len) == 0)
531 void Yaz_ProxyConfig::get_generic_info(int *log_mask,
538 for (ptr = m_proxyPtr->children; ptr; ptr = ptr->next)
540 if (ptr->type == XML_ELEMENT_NODE
541 && !strcmp((const char *) ptr->name, "log"))
543 const char *v = get_text(ptr);
548 while (*cp && *cp != ',' && !isspace(*cp))
551 if (mycmp(v, "client-apdu", len))
552 *log_mask |= PROXY_LOG_APDU_CLIENT;
553 if (mycmp(v, "server-apdu", len))
554 *log_mask |= PROXY_LOG_APDU_SERVER;
555 if (mycmp(v, "client-requests", len))
556 *log_mask |= PROXY_LOG_REQ_CLIENT;
557 if (mycmp(v, "server-requests", len))
558 *log_mask |= PROXY_LOG_REQ_SERVER;
560 *log_mask |= atoi(v);
563 while (*cp && isspace(*cp))
568 if (ptr->type == XML_ELEMENT_NODE &&
569 !strcmp((const char *) ptr->name, "max-clients"))
571 const char *t = get_text(ptr);
574 *max_clients = atoi(t);
575 if (*max_clients < 1)
583 void Yaz_ProxyConfig::get_target_info(const char *name,
588 int *target_idletime,
589 int *client_idletime,
591 int *keepalive_limit_bw,
592 int *keepalive_limit_pdu,
594 const char **cql2rpn,
606 for (ptr = m_proxyPtr->children; ptr; ptr = ptr->next)
608 if (ptr->type == XML_ELEMENT_NODE &&
609 !strcmp((const char *) ptr->name, "max-clients"))
611 const char *t = get_text(ptr);
614 *max_clients = atoi(t);
615 if (*max_clients < 1)
620 ptr = find_target_node(name);
628 return_target_info(ptr, url, limit_bw, limit_pdu, limit_req,
629 target_idletime, client_idletime,
630 keepalive_limit_bw, keepalive_limit_pdu,
631 pre_init, cql2rpn, zeerex);