+void yf::Zoom::Frontend::connect_searchable(mp::Package &package,
+ SearchablePtr sptr,
+ std::string &database,
+ int *error, char **addinfo,
+ mp::odr &odr,
+ int no_out_args,
+ const char **out_names,
+ const char **out_values,
+ std::string content_proxy,
+ std::string proxy,
+ const char *param_content_password,
+ const char *param_content_user,
+ const char *param_nocproxy,
+ const char *param_password,
+ const char *param_retry,
+ const char *param_user,
+ std::string realm)
+{
+ 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");
+ return;
+ }
+ xsp = xsltParseStylesheetDoc(xsp_doc);
+ if (!xsp)
+ {
+ *error = YAZ_BIB1_DATABASE_DOES_NOT_EXIST;
+ *addinfo =
+ odr_strdup(odr,"zoom: xsltParseStylesheetDoc failed "
+ "for literalTransform XSL");
+ xmlFreeDoc(xsp_doc);
+ return;
+ }
+ }
+ 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;
+
+ char fullpath[1024];
+ char *cp = yaz_filepath_resolve(sptr->transform_xsl_fname.c_str(),
+ path, 0, fullpath);
+ if (cp)
+ fname.assign(cp);
+ else
+ {
+ *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
+ *addinfo = (char *)
+ odr_malloc(odr, 40 + sptr->transform_xsl_fname.length());
+ sprintf(*addinfo, "zoom: could not open file %s",
+ sptr->transform_xsl_fname.c_str());
+ return;
+ }
+ xmlDoc *xsp_doc = xmlParseFile(fname.c_str());
+ if (!xsp_doc)
+ {
+ *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
+ *addinfo = (char *) odr_malloc(odr, 50 + fname.length());
+ sprintf(*addinfo, "zoom: xmlParseFile failed for file %s",
+ fname.c_str());
+ return;
+ }
+ xsp = xsltParseStylesheetDoc(xsp_doc);
+ if (!xsp)
+ {
+ *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
+ *addinfo = (char *) odr_malloc(odr, 50 + fname.length());
+ sprintf(*addinfo, "zoom: xsltParseStylesheetDoc failed "
+ "for file %s", fname.c_str());
+ xmlFreeDoc(xsp_doc);
+ return;
+ }
+ }
+
+ cql_transform_t cqlt = 0;
+ if (sptr->rpn2cql_fname.length())
+ {
+ char fullpath[1024];
+ char *cp = yaz_filepath_resolve(sptr->rpn2cql_fname.c_str(),
+ m_p->file_path.c_str(), 0, fullpath);
+ if (cp)
+ cqlt = cql_transform_open_fname(fullpath);
+ }
+ else
+ cqlt = cql_transform_create();
+
+ if (!cqlt)
+ {
+ *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
+ *addinfo = odr_strdup(odr, "zoom: missing/invalid cql2rpn file");
+ xsltFreeStylesheet(xsp);
+ return;
+ }
+
+ BackendPtr b(new Backend);
+
+ b->cqlt = cqlt;
+ b->sptr = sptr;
+ b->xsp = xsp;
+ b->enable_cproxy = param_nocproxy ? false : true;
+
+ if (param_retry)
+ b->retry_on_failure = param_retry;
+ else
+ b->retry_on_failure = b->sptr->retry_on_failure;
+
+ if (sptr->query_encoding.length())
+ b->set_option("rpnCharset", sptr->query_encoding);
+
+ std::string extraArgs = sptr->extraArgs;
+
+ b->set_option("timeout", m_p->zoom_timeout.c_str());
+
+ if (m_p->apdu_log)
+ b->set_option("apdulog", "1");
+
+ if (sptr->piggyback && sptr->sru.length())
+ b->set_option("count", "1"); /* some SRU servers INSIST on getting
+ maximumRecords > 0 */
+ b->set_option("piggyback", sptr->piggyback ? "1" : "0");
+
+ std::string authentication = sptr->authentication;
+ if (param_user)
+ {
+ authentication = std::string(param_user);
+ if (param_password)
+ authentication += "/" + std::string(param_password);
+ }
+ std::string content_authentication = sptr->contentAuthentication;
+ if (param_content_user)
+ {
+ content_authentication = std::string(param_content_user);
+ if (param_content_password)
+ content_authentication += "/" + std::string(param_content_password);
+ }
+
+ if (proxy.length() == 0)
+ proxy = sptr->cfProxy;
+ b->m_proxy = proxy;
+
+ if (sptr->cfAuth.length())
+ {
+ // A CF target
+ b->set_option("user", sptr->cfAuth);
+ if (param_user)
+ {
+ out_names[no_out_args] = "user";
+ out_values[no_out_args++] = odr_strdup(odr, param_user);
+ if (param_password)
+ {
+ out_names[no_out_args] = "password";
+ out_values[no_out_args++] = odr_strdup(odr, param_password);
+ }
+ }
+ else if (authentication.length())
+ {
+ size_t found = authentication.find('/');
+ if (found != std::string::npos)
+ {
+ out_names[no_out_args] = "user";
+ out_values[no_out_args++] =
+ odr_strdup(odr, authentication.substr(0, found).c_str());
+
+ out_names[no_out_args] = "password";
+ out_values[no_out_args++] =
+ odr_strdup(odr, authentication.substr(found+1).c_str());
+ }
+ else
+ {
+ out_names[no_out_args] = "user";
+ out_values[no_out_args++] =
+ odr_strdup(odr, authentication.c_str());
+ }
+ }
+ if (proxy.length())
+ {
+ out_names[no_out_args] = "proxy";
+ out_values[no_out_args++] = odr_strdup(odr, proxy.c_str());
+ }
+ if (sptr->cfSubDB.length())
+ {
+ out_names[no_out_args] = "subdatabase";
+ out_values[no_out_args++] = odr_strdup(odr, sptr->cfSubDB.c_str());
+ }
+ if (!param_nocproxy && b->sptr->contentConnector.length())
+ param_nocproxy = "1";
+
+ if (param_nocproxy)
+ {
+ out_names[no_out_args] = "nocproxy";
+ out_values[no_out_args++] = odr_strdup(odr, param_nocproxy);
+ }
+ }
+ else
+ {
+ const char *auth = authentication.c_str();
+ const char *cp1 = strchr(auth, ' ');
+ if (!cp1 && sptr->sru.length())
+ cp1 = strchr(auth, '/');
+ if (!cp1)
+ {
+ /* Z39.50 user/password style, or no password for SRU */
+ b->set_option("user", auth);
+ }
+ else
+ {
+ /* now consider group as well */
+ const char *cp2 = strchr(cp1 + 1, ' ');
+
+ b->set_option("user", auth, cp1 - auth);
+ if (!cp2)
+ b->set_option("password", cp1 + 1);
+ else
+ {
+ b->set_option("group", cp1 + 1, cp2 - cp1 - 1);
+ b->set_option("password", cp2 + 1);
+ }
+ }
+ if (sptr->authenticationMode.length())
+ b->set_option("authenticationMode", sptr->authenticationMode);
+ if (proxy.length())
+ b->set_option("proxy", proxy);
+ }
+ if (extraArgs.length())
+ b->set_option("extraArgs", extraArgs);
+
+ std::string url(sptr->target);
+ if (sptr->sru.length())
+ {
+ b->set_option("sru", sptr->sru);
+ if (url.find("://") == std::string::npos)
+ url = "http://" + url;
+ if (sptr->sru_version.length())
+ b->set_option("sru_version", sptr->sru_version);
+ }
+ if (no_out_args)
+ {
+ char *x_args = 0;
+ out_names[no_out_args] = 0; // terminate list
+
+ yaz_array_to_uri(&x_args, odr, (char **) out_names,
+ (char **) out_values);
+ url += "," + std::string(x_args);
+ }
+ package.log("zoom", YLOG_LOG, "url: %s", url.c_str());
+ b->connect(url, error, addinfo, odr);
+ if (*error == 0 && b->enable_cproxy)
+ create_content_session(package, b, error, addinfo, odr,
+ content_authentication.length() ?
+ content_authentication : authentication,
+ content_proxy.length() ? content_proxy : proxy,
+ realm);
+ if (*error == 0)
+ {
+ m_backend_list.push_back(b);
+ }
+}
+
+void yf::Zoom::Frontend::get_backend_from_databases(