2 * Copyright (c) 1998-2003, Index Data.
3 * See the file LICENSE for details.
5 * $Id: yaz-proxy-config.cpp,v 1.14 2003-11-25 21:54:18 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,
125 for (; ptr; ptr = ptr->next)
127 if (ptr->type == XML_ELEMENT_NODE
128 && !strcmp((const char *) ptr->name, "preinit"))
130 const char *v = get_text(ptr);
131 *pre_init = v ? atoi(v) : 1;
133 if (ptr->type == XML_ELEMENT_NODE
134 && !strcmp((const char *) ptr->name, "url"))
136 const char *t = get_text(ptr);
137 if (t && no_url < MAX_ZURL_PLEX)
143 if (ptr->type == XML_ELEMENT_NODE
144 && !strcmp((const char *) ptr->name, "keepalive"))
147 *keepalive_limit_bw = 500000;
148 *keepalive_limit_pdu = 1000;
149 return_limit(ptr, keepalive_limit_bw, keepalive_limit_pdu,
152 if (ptr->type == XML_ELEMENT_NODE
153 && !strcmp((const char *) ptr->name, "limit"))
154 return_limit(ptr, limit_bw, limit_pdu, limit_req);
155 if (ptr->type == XML_ELEMENT_NODE
156 && !strcmp((const char *) ptr->name, "target-timeout"))
158 const char *t = get_text(ptr);
161 *target_idletime = atoi(t);
162 if (*target_idletime < 0)
163 *target_idletime = 0;
166 if (ptr->type == XML_ELEMENT_NODE
167 && !strcmp((const char *) ptr->name, "client-timeout"))
169 const char *t = get_text(ptr);
172 *client_idletime = atoi(t);
173 if (*client_idletime < 0)
174 *client_idletime = 0;
181 int Yaz_ProxyConfig::atoi_l(const char **cp)
184 while (**cp && isdigit(**cp))
186 v = v*10 + (**cp - '0');
192 int Yaz_ProxyConfig::match_list(int v, const char *m)
196 while(*m && isspace(*m))
207 if (v >= l && v <= h)
216 int Yaz_ProxyConfig::check_type_1_attributes(ODR odr, xmlNodePtr ptrl,
217 Z_AttributeList *attrs,
221 for (i = 0; i<attrs->num_attributes; i++)
223 Z_AttributeElement *el = attrs->attributes[i];
225 if (!el->attributeType)
227 int type = *el->attributeType;
230 if (el->which == Z_AttributeValue_numeric && el->value.numeric)
231 value = el->value.numeric;
234 for(ptr = ptrl->children; ptr; ptr = ptr->next)
236 if (ptr->type == XML_ELEMENT_NODE &&
237 !strcmp((const char *) ptr->name, "attribute"))
239 const char *match_type = 0;
240 const char *match_value = 0;
241 const char *match_error = 0;
242 struct _xmlAttr *attr;
243 for (attr = ptr->properties; attr; attr = attr->next)
245 if (!strcmp((const char *) attr->name, "type") &&
246 attr->children && attr->children->type == XML_TEXT_NODE)
247 match_type = (const char *) attr->children->content;
248 if (!strcmp((const char *) attr->name, "value") &&
249 attr->children && attr->children->type == XML_TEXT_NODE)
250 match_value = (const char *) attr->children->content;
251 if (!strcmp((const char *) attr->name, "error") &&
252 attr->children && attr->children->type == XML_TEXT_NODE)
253 match_error = (const char *) attr->children->content;
255 if (match_type && match_value)
257 char addinfo_str[20];
258 if (!match_list(type, match_type))
262 if (!strcmp(match_type, "*"))
263 sprintf (addinfo_str, "%d", type);
266 if (!match_list(*value, match_value))
268 sprintf (addinfo_str, "%d", *value);
276 *addinfo = odr_strdup(odr, addinfo_str);
277 return atoi(match_error);
289 int Yaz_ProxyConfig::check_type_1_structure(ODR odr, xmlNodePtr ptr,
293 if (q->which == Z_RPNStructure_complex)
295 int e = check_type_1_structure(odr, ptr, q->u.complex->s1, addinfo);
298 e = check_type_1_structure(odr, ptr, q->u.complex->s2, addinfo);
301 else if (q->which == Z_RPNStructure_simple)
303 if (q->u.simple->which == Z_Operand_APT)
305 return check_type_1_attributes(
306 odr, ptr, q->u.simple->u.attributesPlusTerm->attributes,
315 int Yaz_ProxyConfig::check_type_1(ODR odr, xmlNodePtr ptr, Z_RPNQuery *query,
318 // possibly check for Bib-1
319 return check_type_1_structure(odr, ptr, query->RPNStructure, addinfo);
323 int Yaz_ProxyConfig::check_query(ODR odr, const char *name, Z_Query *query,
329 ptr = find_target_node(name);
332 if (query->which == Z_Query_type_1 || query->which == Z_Query_type_101)
333 return check_type_1(odr, ptr, query->u.type_1, addinfo);
339 int Yaz_ProxyConfig::check_syntax(ODR odr, const char *name,
340 Odr_oid *syntax, char **addinfo)
345 ptr = find_target_node(name);
348 for(ptr = ptr->children; ptr; ptr = ptr->next)
350 if (ptr->type == XML_ELEMENT_NODE &&
351 !strcmp((const char *) ptr->name, "syntax"))
353 int match = 0; // if we match record syntax
354 const char *match_type = 0;
355 const char *match_error = 0;
356 const char *match_marcxml = 0;
357 struct _xmlAttr *attr;
358 for (attr = ptr->properties; attr; attr = attr->next)
360 if (!strcmp((const char *) attr->name, "type") &&
361 attr->children && attr->children->type == XML_TEXT_NODE)
362 match_type = (const char *) attr->children->content;
363 if (!strcmp((const char *) attr->name, "error") &&
364 attr->children && attr->children->type == XML_TEXT_NODE)
365 match_error = (const char *) attr->children->content;
366 if (!strcmp((const char *) attr->name, "marcxml") &&
367 attr->children && attr->children->type == XML_TEXT_NODE)
368 match_marcxml = (const char *) attr->children->content;
372 if (!strcmp(match_type, "*"))
374 else if (!strcmp(match_type, "none"))
381 int match_oid[OID_SIZE];
382 oid_name_to_oid(CLASS_RECSYN, match_type, match_oid);
383 if (oid_oidcmp(match_oid, syntax) == 0)
397 char dotoid_str[100];
398 oid_to_dotstring(syntax, dotoid_str);
399 *addinfo = odr_strdup(odr, dotoid_str);
401 return atoi(match_error);
412 xmlNodePtr Yaz_ProxyConfig::find_target_node(const char *name)
417 for (ptr = m_proxyPtr->children; ptr; ptr = ptr->next)
419 if (ptr->type == XML_ELEMENT_NODE &&
420 !strcmp((const char *) ptr->name, "target"))
425 // <target default="1"> ?
426 struct _xmlAttr *attr;
427 for (attr = ptr->properties; attr; attr = attr->next)
428 if (!strcmp((const char *) attr->name, "default") &&
429 attr->children && attr->children->type == XML_TEXT_NODE)
431 xmlChar *t = attr->children->content;
438 // <target name="name"> ?
439 struct _xmlAttr *attr;
440 for (attr = ptr->properties; attr; attr = attr->next)
441 if (!strcmp((const char *) attr->name, "name"))
444 && attr->children->type==XML_TEXT_NODE
445 && attr->children->content
446 && (!strcmp((const char *) attr->children->content,
448 || !strcmp((const char *) attr->children->content,
461 int Yaz_ProxyConfig::get_target_no(int no,
467 int *target_idletime,
468 int *client_idletime,
470 int *keepalive_limit_bw,
471 int *keepalive_limit_pdu,
479 for (ptr = m_proxyPtr->children; ptr; ptr = ptr->next)
480 if (ptr->type == XML_ELEMENT_NODE &&
481 !strcmp((const char *) ptr->name, "target"))
485 struct _xmlAttr *attr;
486 for (attr = ptr->properties; attr; attr = attr->next)
487 if (!strcmp((const char *) attr->name, "name"))
490 && attr->children->type==XML_TEXT_NODE
491 && attr->children->content)
492 *name = (const char *) attr->children->content;
494 return_target_info(ptr, url, limit_bw, limit_pdu, limit_req,
495 target_idletime, client_idletime,
496 keepalive_limit_bw, keepalive_limit_pdu,
506 int Yaz_ProxyConfig::mycmp(const char *hay, const char *item, size_t len)
508 if (len == strlen(item) && memcmp(hay, item, len) == 0)
513 void Yaz_ProxyConfig::get_generic_info(int *log_mask,
520 for (ptr = m_proxyPtr->children; ptr; ptr = ptr->next)
522 if (ptr->type == XML_ELEMENT_NODE
523 && !strcmp((const char *) ptr->name, "log"))
525 const char *v = get_text(ptr);
530 while (*cp && *cp != ',' && !isspace(*cp))
533 if (mycmp(v, "client-apdu", len))
534 *log_mask |= PROXY_LOG_APDU_CLIENT;
535 if (mycmp(v, "server-apdu", len))
536 *log_mask |= PROXY_LOG_APDU_SERVER;
537 if (mycmp(v, "client-requests", len))
538 *log_mask |= PROXY_LOG_REQ_CLIENT;
539 if (mycmp(v, "server-requests", len))
540 *log_mask |= PROXY_LOG_REQ_SERVER;
542 *log_mask |= atoi(v);
545 while (*cp && isspace(*cp))
550 if (ptr->type == XML_ELEMENT_NODE &&
551 !strcmp((const char *) ptr->name, "max-clients"))
553 const char *t = get_text(ptr);
556 *max_clients = atoi(t);
557 if (*max_clients < 1)
565 void Yaz_ProxyConfig::get_target_info(const char *name,
570 int *target_idletime,
571 int *client_idletime,
573 int *keepalive_limit_bw,
574 int *keepalive_limit_pdu,
586 for (ptr = m_proxyPtr->children; ptr; ptr = ptr->next)
588 if (ptr->type == XML_ELEMENT_NODE &&
589 !strcmp((const char *) ptr->name, "max-clients"))
591 const char *t = get_text(ptr);
594 *max_clients = atoi(t);
595 if (*max_clients < 1)
600 ptr = find_target_node(name);
608 return_target_info(ptr, url, limit_bw, limit_pdu, limit_req,
609 target_idletime, client_idletime,
610 keepalive_limit_bw, keepalive_limit_pdu,