+ std::string input_args;
+ std::string torus_db;
+ size_t db_arg_pos = database.find(',');
+ if (db_arg_pos != std::string::npos)
+ {
+ torus_db = database.substr(0, db_arg_pos);
+ input_args = database.substr(db_arg_pos + 1);
+ }
+ else
+ torus_db = database;
+
+ std::string content_proxy;
+ std::string realm = session_realm;
+ if (realm.length() == 0)
+ realm = m_p->default_realm;
+
+ const char *param_user = 0;
+ const char *param_password = 0;
+ const char *param_content_user = 0;
+ const char *param_content_password = 0;
+ const char *param_nocproxy = 0;
+ const char *param_retry = 0;
+ int no_parms = 0;
+
+ char **names;
+ char **values;
+ int no_out_args = 0;
+ if (input_args.length())
+ no_parms = yaz_uri_to_array(input_args.c_str(),
+ odr, &names, &values);
+ // adding 10 because we'll be adding other URL args
+ const char **out_names = (const char **)
+ odr_malloc(odr, (10 + no_parms) * sizeof(*out_names));
+ const char **out_values = (const char **)
+ odr_malloc(odr, (10 + no_parms) * sizeof(*out_values));
+
+ // may be changed if it's a content connection
+ std::string torus_url = m_p->torus_searchable_url;
+ int i;
+ for (i = 0; i < no_parms; i++)
+ {
+ const char *name = names[i];
+ const char *value = values[i];
+ assert(name);
+ assert(value);
+ if (!strcmp(name, "user"))
+ param_user = value;
+ else if (!strcmp(name, "password"))
+ param_password = value;
+ else if (!strcmp(name, "content-user"))
+ param_content_user = value;
+ else if (!strcmp(name, "content-password"))
+ param_content_password = value;
+ else if (!strcmp(name, "content-proxy"))
+ content_proxy = value;
+ else if (!strcmp(name, "nocproxy"))
+ param_nocproxy = value;
+ else if (!strcmp(name, "retry"))
+ param_retry = value;
+ else if (!strcmp(name, "proxy"))
+ {
+ char **dstr;
+ int dnum = 0;
+ nmem_strsplit(((ODR) odr)->mem, ",", value, &dstr, &dnum);
+ if (connection_reuse)
+ {
+ // find the step after our current proxy
+ int i;
+ for (i = 0; i < dnum; i++)
+ if (!strcmp(proxy.c_str(), dstr[i]))
+ break;
+ if (i >= dnum - 1)
+ *proxy_step = 0;
+ else
+ *proxy_step = i + 1;
+ }
+ else
+ {
+ // step is known.. Guess our proxy from it
+ if (*proxy_step >= dnum)
+ *proxy_step = 0;
+ else
+ {
+ proxy = dstr[*proxy_step];
+
+ (*proxy_step)++;
+ if (*proxy_step == dnum)
+ *proxy_step = 0;
+ }
+ }
+ }
+ else if (!strcmp(name, "cproxysession"))
+ {
+ out_names[no_out_args] = name;
+ out_values[no_out_args++] = value;
+ torus_url = m_p->torus_content_url;
+ }
+ else if (!strcmp(name, "realm") && session_realm.length() == 0)
+ realm = value;
+ else if (!strcmp(name, "torus_url") && session_realm.length() == 0)
+ torus_url = value;
+ else if (name[0] == 'x' && name[1] == '-')
+ {
+ out_names[no_out_args] = name;
+ out_values[no_out_args++] = value;
+ }
+ else
+ {
+ BackendPtr notfound;
+ char *msg = (char*) odr_malloc(odr, strlen(name) + 30);
+ *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
+ sprintf(msg, "zoom: bad database argument: %s", name);
+ *addinfo = msg;
+ return;
+ }
+ }
+ if (proxy.length())
+ package.log("zoom", YLOG_LOG, "proxy: %s", proxy.c_str());
+
+ if (connection_reuse)
+ {
+ std::list<BackendPtr>::iterator it = m_backend_list.begin();
+ for (; it != m_backend_list.end(); it++)
+ (*it)->connect("", error, addinfo, odr);
+ return;
+ }
+
+ m_frontend_database = database;
+ m_backend_list.clear();
+
+ if (torus_db.compare("IR-Explain---1") == 0)
+ return explain_search(package, database, error, addinfo, odr, torus_url,
+ torus_db, realm);
+ enable_explain = false;
+
+ SearchablePtr sptr;
+
+ std::map<std::string,SearchablePtr>::iterator it;
+ it = m_p->s_map.find(torus_db);
+ if (it != m_p->s_map.end())
+ {
+ sptr = it->second;
+ connect_searchable(package, sptr, database, error, addinfo, odr,
+ no_out_args, out_names, out_values,
+ content_proxy, proxy,
+ param_content_password,
+ param_content_user,
+ param_nocproxy,
+ param_password,
+ param_retry,
+ param_user,
+ realm);
+ }
+ else if (torus_db == "all_local")
+ {
+ for (it = m_p->s_map.begin(); it != m_p->s_map.end(); it++)
+ {
+ sptr = it->second;
+ connect_searchable(package, sptr, database, error, addinfo, odr,
+ no_out_args, out_names, out_values,
+ content_proxy, proxy,
+ param_content_password,
+ param_content_user,
+ param_nocproxy,
+ param_password,
+ param_retry,
+ param_user,
+ realm);
+ }
+ }
+ else if (torus_url.length() > 0)
+ {
+ std::string torus_addinfo;
+ std::string torus_query = "udb==" + torus_db;
+ xmlDoc *doc = mp::get_searchable(package,torus_url, torus_db,
+ torus_query,
+ realm, m_p->proxy,
+ torus_addinfo);
+ if (!doc)
+ {
+ *error = YAZ_BIB1_UNSPECIFIED_ERROR;
+ if (torus_addinfo.length())
+ *addinfo = odr_strdup(odr, torus_addinfo.c_str());
+ return;
+ }
+ const xmlNode *ptr = xmlDocGetRootElement(doc);
+ if (ptr && ptr->type == XML_ELEMENT_NODE)
+ {
+ if (!strcmp((const char *) ptr->name, "record"))
+ {
+ sptr = m_p->parse_torus_record(ptr);
+ connect_searchable(package, sptr, database,
+ error, addinfo, odr,
+ no_out_args, out_names, out_values,
+ content_proxy, proxy,
+ param_content_password,
+ param_content_user,
+ param_nocproxy,
+ param_password,
+ param_retry,
+ param_user,
+ realm);
+ }
+ else if (!strcmp((const char *) ptr->name, "records"))
+ {
+ for (ptr = ptr->children; ptr; ptr = ptr->next)
+ {
+ if (ptr->type == XML_ELEMENT_NODE
+ && !strcmp((const char *) ptr->name, "record"))
+ {
+ if (sptr)
+ {
+ *error = YAZ_BIB1_UNSPECIFIED_ERROR;
+ *addinfo = (char*)
+ odr_malloc(odr, 40 + torus_db.length());
+ sprintf(*addinfo, "multiple records for udb=%s",
+ database.c_str());
+ xmlFreeDoc(doc);
+ return;
+ }
+ sptr = m_p->parse_torus_record(ptr);
+ connect_searchable(package, sptr, database,
+ error, addinfo, odr,
+ no_out_args, out_names, out_values,
+ content_proxy, proxy,
+ param_content_password,
+ param_content_user,
+ param_nocproxy,
+ param_password,
+ param_retry,
+ param_user,
+ realm);
+ }
+ }
+ }
+ else
+ {
+ *error = YAZ_BIB1_UNSPECIFIED_ERROR;
+ *addinfo = (char*) odr_malloc(
+ odr, 40 + strlen((const char *) ptr->name));
+ sprintf(*addinfo, "bad root element for torus: %s", ptr->name);
+ xmlFreeDoc(doc);
+ return;
+ }
+ }
+ xmlFreeDoc(doc);
+ }
+
+ if (m_backend_list.size() == 0)
+ {
+ *error = YAZ_BIB1_DATABASE_DOES_NOT_EXIST;
+ *addinfo = odr_strdup(odr, torus_db.c_str());
+ }
+}
+
+void yf::Zoom::Frontend::prepare_elements(BackendPtr b,
+ Odr_oid *preferredRecordSyntax,
+ const char *element_set_name,
+ bool &enable_pz2_retrieval,
+ bool &enable_pz2_transform,
+ bool &enable_record_transform,
+ bool &assume_marc8_charset)
+{
+ char oid_name_str[OID_STR_MAX];
+ const char *syntax_name = 0;
+
+ if (preferredRecordSyntax &&
+ !oid_oidcmp(preferredRecordSyntax, yaz_oid_recsyn_xml))
+ {
+ if (element_set_name &&
+ !strcmp(element_set_name, m_p->element_transform.c_str()))
+ {
+ enable_pz2_retrieval = true;
+ enable_pz2_transform = true;
+ }
+ else if (element_set_name &&
+ !strcmp(element_set_name, m_p->element_raw.c_str()))
+ {
+ enable_pz2_retrieval = true;
+ }
+ else if (m_p->record_xsp)
+ {
+ enable_pz2_retrieval = true;
+ enable_pz2_transform = true;
+ enable_record_transform = true;
+ }
+ }
+
+ if (enable_pz2_retrieval)
+ {