+ 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;
+ 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, "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 notfound;
+ }
+ }
+ if (proxy.length())
+ package.log("zoom", YLOG_LOG, "proxy: %s", proxy.c_str());
+
+ if (connection_reuse)
+ {
+ m_backend->connect("", error, addinfo, odr);
+ return m_backend;
+ }
+
+ if (param_user)
+ {
+ authentication = std::string(param_user);
+ if (param_password)
+ authentication += "/" + std::string(param_password);
+ }
+ if (param_content_user)
+ {
+ content_authentication = std::string(param_content_user);
+ if (param_content_password)
+ content_authentication += "/" + std::string(param_content_password);
+ }
+
+ if (torus_db.compare("IR-Explain---1") == 0)
+ return explain_search(package, database, error, addinfo, odr, torus_url,
+ torus_db, realm);
+
+ 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;
+ else if (torus_url.length() > 0)
+ {
+ std::string torus_query = "udb==" + torus_db;
+ xmlDoc *doc = mp::get_searchable(package,torus_url, torus_db,
+ torus_query,
+ realm, m_p->proxy);
+ if (!doc)
+ {
+ *error = YAZ_BIB1_UNSPECIFIED_ERROR;
+ *addinfo = odr_strdup(odr, "Torus server unavailable or "
+ "incorrectly configured");
+ BackendPtr b;
+ return b;
+ }
+ 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);
+ }
+ 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);
+ BackendPtr b;
+ return b;
+ }
+ sptr = m_p->parse_torus_record(ptr);
+ }
+ }
+ }
+ 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);
+ BackendPtr b;
+ return b;
+ }
+ }
+ xmlFreeDoc(doc);
+ }
+
+ if (!sptr)
+ {
+ *error = YAZ_BIB1_DATABASE_DOES_NOT_EXIST;
+ *addinfo = odr_strdup(odr, torus_db.c_str());
+ BackendPtr b;
+ return b;
+ }
+
+ xsltStylesheetPtr xsp = 0;
+ if (sptr->transform_xsl_content.length())
+ {
+ xmlDoc *xsp_doc = xmlParseMemory(sptr->transform_xsl_content.c_str(),
+ sptr->transform_xsl_content.length());
+ if (!xsp_doc)
+ {
+ *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
+ *addinfo = odr_strdup(odr, "zoom: xmlParseMemory failed "
+ "for literalTransform XSL");
+ BackendPtr b;
+ return b;
+ }
+ xsp = xsltParseStylesheetDoc(xsp_doc);
+ if (!xsp)
+ {
+ *error = YAZ_BIB1_DATABASE_DOES_NOT_EXIST;
+ *addinfo =
+ odr_strdup(odr,"zoom: xsltParseStylesheetDoc failed "
+ "for literalTransform XSL");
+ BackendPtr b;
+ xmlFreeDoc(xsp_doc);
+ return b;
+ }
+ }
+ else if (sptr->transform_xsl_fname.length())
+ {
+ const char *path = 0;
+
+ if (m_p->xsldir.length())
+ path = m_p->xsldir.c_str();
+ else
+ path = m_p->file_path.c_str();
+ std::string fname;