+ 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());
+ BackendPtr b;
+ return b;
+ }
+ 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());
+ BackendPtr b;
+ return b;
+ }
+ 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());
+ BackendPtr b;
+ xmlFreeDoc(xsp_doc);
+ return b;
+ }
+ }
+
+ 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");
+ BackendPtr b;
+ xsltFreeStylesheet(xsp);
+ return b;
+ }
+
+ m_backend.reset();
+
+ BackendPtr b(new Backend);
+
+ b->cqlt = cqlt;
+ b->sptr = sptr;
+ b->xsp = xsp;
+ b->m_frontend_database = database;
+ b->enable_cproxy = param_nocproxy ? false : true;
+
+ 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");
+
+ if (authentication.length() == 0)
+ authentication = sptr->authentication;
+
+ 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 (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)
+ {
+ out_names[no_out_args] = "nocproxy";
+ out_values[no_out_args++] = odr_strdup(odr, param_nocproxy);
+ }
+ }
+ else
+ {
+ if (sptr->sru.length() == 0)
+ b->set_option("user", authentication); /* Z39.50 */
+ else
+ {
+ std::string user;
+ std::string password;
+ std::string authtype = sptr->authenticationMode;
+
+ {
+ const char *cstr = authentication.c_str();
+ const char *cp1 = strchr(cstr, '/');
+ if (cp1)
+ {
+ password.assign(cp1 + 1);
+ user.assign(cstr, cp1 - cstr);
+ }
+ else
+ user.assign(cstr);
+ }
+
+ if (authtype.compare("url") == 0)
+ {
+ /* SRU URL encoding of auth stuff */
+ ODR o = odr_createmem(ODR_ENCODE);
+ char *path = 0;
+ const char *names[3];
+ const char *values[3];
+
+ names[0] = "x-username";
+ values[0] = user.c_str();
+ names[1] = "x-password";
+ values[1] = password.c_str();
+ names[2] = 0;
+ values[2] = 0;
+
+ yaz_array_to_uri(&path, o, (char **) names, (char **) values);
+ if (extraArgs.length())
+ extraArgs.append("&");
+ extraArgs.append(path);
+ odr_destroy(o);
+ }
+ else
+ {
+ b->set_option("user", user);
+ if (password.length())
+ b->set_option("password", password);
+ }
+ }
+ 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 = b;
+ return b;
+}
+
+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)
+{