+ Z_ExtendedServicesResponse *res =
+ z_res->u.extendedServicesResponse;
+ switch (*res->operationStatus)
+ {
+ case Z_ExtendedServicesResponse_done:
+ wrbuf_puts(w, "DONE"); break;
+ case Z_ExtendedServicesResponse_accepted:
+ wrbuf_puts(w, "ACCEPTED"); break;
+ case Z_ExtendedServicesResponse_failure:
+ wrbuf_puts(w, "ERROR"); break;
+ default:
+ wrbuf_printf(w, ODR_INT_PRINTF, *res->operationStatus);
+ }
+ wrbuf_puts(w, " ");
+ if (res->diagnostics && res->num_diagnostics >= 1)
+ log_DiagRecs(w, res->num_diagnostics,res->diagnostics);
+ else
+ wrbuf_puts(w, "-");
+ }
+ break;
+ case Z_APDU_close:
+ wrbuf_puts(w, "close");
+ break;
+ case Z_APDU_duplicateDetectionRequest:
+ wrbuf_puts(w, "duplicateDetention ");
+ if (!z_res)
+ wrbuf_puts(w, "?");
+ else if (z_res->which != Z_APDU_duplicateDetectionResponse)
+ wrbuf_printf(w, "? response=%d", z_res->which);
+ else
+ {
+ Z_DuplicateDetectionResponse *res =
+ z_res->u.duplicateDetectionResponse;
+ if (*res->status)
+ wrbuf_puts(w, "OK");
+ else
+ wrbuf_puts(w, "ERROR");
+
+ wrbuf_puts(w, " ");
+ if (res->diagnostics && res->num_diagnostics >= 1)
+ log_DiagRecs(w, res->num_diagnostics, res->diagnostics);
+ else
+ wrbuf_puts(w, "-");
+ }
+ break;
+ default:
+ wrbuf_printf(w, "REQ=%d RES=%d", z_req->which, z_res->which);
+ }
+}
+
+
+static void log_1line_Z_HTTP(Z_HTTP_Request *req, Z_HTTP_Response *res, WRBUF w)
+{
+ wrbuf_printf(w, "%s %s HTTP/%s", req->method, req->path, req->version);
+ if (res)
+ wrbuf_printf(w, " %d %d", res->code, res->content_len);
+ else
+ wrbuf_printf(w, " ?");
+}
+
+static void log_1line_Z_GDU(Z_GDU *gdu_req, Z_GDU *gdu_res, WRBUF w)
+{
+ if (gdu_req && gdu_req->which == Z_GDU_Z3950)
+ {
+ log_1line_Z_APDU(gdu_req->u.z3950,
+ (gdu_res && gdu_res->which == Z_GDU_Z3950) ?
+ gdu_res->u.z3950 : 0, w);
+ }
+ else if (gdu_req && gdu_req->which == Z_GDU_HTTP_Request)
+ {
+ log_1line_Z_HTTP(gdu_req->u.HTTP_Request,
+ (gdu_res && gdu_res->which == Z_GDU_HTTP_Response) ?
+ gdu_res->u.HTTP_Response : 0, w);
+ }
+}
+
+void yf::Log::Impl::configure(const xmlNode *ptr)
+{
+ for (ptr = ptr->children; ptr; ptr = ptr->next)
+ {
+ if (ptr->type != XML_ELEMENT_NODE)
+ continue;
+ if (!strcmp((const char *) ptr->name, "message"))
+ m_msg_config = mp::xml::get_text(ptr);
+ else if (!strcmp((const char *) ptr->name, "filename"))
+ {
+ std::string fname = mp::xml::get_text(ptr);
+ openfile(fname);
+ }
+ else if (!strcmp((const char *) ptr->name, "time-format"))
+ {
+ m_time_format = mp::xml::get_text(ptr);
+ }
+ else if (!strcmp((const char *) ptr->name, "category"))
+ {
+ const struct _xmlAttr *attr;
+ for (attr = ptr->properties; attr; attr = attr->next)
+ {
+ if (!strcmp((const char *) attr->name, "line"))
+ m_1line = mp::xml::get_bool(attr->children, true);
+ else if (!strcmp((const char *) attr->name, "access"))
+ m_access = mp::xml::get_bool(attr->children, true);
+ else if (!strcmp((const char *) attr->name, "user-access"))
+ m_user_access = mp::xml::get_bool(attr->children, true);
+ else if (!strcmp((const char *) attr->name, "request-apdu"))
+ m_req_apdu = mp::xml::get_bool(attr->children, true);
+ else if (!strcmp((const char *) attr->name, "response-apdu"))
+ m_res_apdu = mp::xml::get_bool(attr->children, true);
+ else if (!strcmp((const char *) attr->name, "apdu"))
+ {
+ m_req_apdu = mp::xml::get_bool(attr->children, true);
+ m_res_apdu = m_req_apdu;
+ }
+ else if (!strcmp((const char *) attr->name,
+ "request-session"))
+ m_req_session =
+ mp::xml::get_bool(attr->children, true);
+ else if (!strcmp((const char *) attr->name,
+ "response-session"))
+ m_res_session =
+ mp::xml::get_bool(attr->children, true);
+ else if (!strcmp((const char *) attr->name,
+ "session"))
+ {
+ m_req_session =
+ mp::xml::get_bool(attr->children, true);
+ m_res_session = m_req_session;
+ }
+ else if (!strcmp((const char *) attr->name,
+ "init-options"))
+ m_init_options =
+ mp::xml::get_bool(attr->children, true);
+ else if (!strcmp((const char *) attr->name,
+ "init-options"))
+ m_init_options =
+ mp::xml::get_bool(attr->children, true);
+ else
+ throw mp::filter::FilterException(
+ "Bad attribute " + std::string((const char *)
+ attr->name));
+ }
+ }
+ else
+ {
+ throw mp::filter::FilterException("Bad element "
+ + std::string((const char *)
+ ptr->name));
+ }
+ }
+}
+
+void yf::Log::Impl::process(mp::Package &package)
+{
+ Z_GDU *gdu_req = package.request().get();
+ std::string user("-");
+
+ yaz_timing_t timer = yaz_timing_create();
+
+ // scope for session lock
+ {
+ boost::mutex::scoped_lock scoped_lock(m_session_mutex);
+
+ if (gdu_req && gdu_req->which == Z_GDU_Z3950)
+ {
+ Z_APDU *apdu_req = gdu_req->u.z3950;
+ if (apdu_req->which == Z_APDU_initRequest)
+ {
+ Z_InitRequest *req = apdu_req->u.initRequest;
+ Z_IdAuthentication *a = req->idAuthentication;
+ if (a)
+ {
+ if (a->which == Z_IdAuthentication_idPass)
+ user = a->u.idPass->userId;
+ else if (a->which == Z_IdAuthentication_open)
+ user = a->u.open;
+
+ m_sessions[package.session()] = user;
+ }
+ }
+ }
+ std::map<mp::Session,std::string>::iterator it =
+ m_sessions.find(package.session());
+ if (it != m_sessions.end())
+ user = it->second;
+
+ if (package.session().is_closed())
+ m_sessions.erase(package.session());
+ }
+ // scope for locking Ostream
+ {
+ boost::mutex::scoped_lock scoped_lock(m_file->m_mutex);
+
+ if (m_access)
+ {
+ if (gdu_req)
+ {
+ std::ostringstream os;
+ os << m_msg_config << " "
+ << package << " "
+ << "0.000000" << " "
+ << *gdu_req;
+ m_file->log(m_time_format, os);
+ }
+ }
+
+ if (m_user_access)
+ {
+ if (gdu_req)
+ {
+ std::ostringstream os;
+ os << m_msg_config << " " << user << " "
+ << package << " "
+ << "0.000000" << " "
+ << *gdu_req;
+ m_file->log(m_time_format, os);
+ }
+ }
+
+ if (m_req_session)
+ {
+ std::ostringstream os;
+ os << m_msg_config;
+ os << " request id=" << package.session().id();
+ os << " close="
+ << (package.session().is_closed() ? "yes" : "no");
+ m_file->log(m_time_format, os);
+ }
+
+ if (m_init_options)
+ {
+ if (gdu_req && gdu_req->which == Z_GDU_Z3950 &&
+ gdu_req->u.z3950->which == Z_APDU_initRequest)
+ {
+ std::ostringstream os;
+ os << m_msg_config << " init options:";
+ yaz_init_opt_decode(gdu_req->u.z3950->u.initRequest->options,
+ option_write, &os);
+ m_file->log(m_time_format, os);
+ }
+ }
+
+ if (m_req_apdu)
+ {
+ if (gdu_req)
+ {
+ mp::odr odr(ODR_PRINT);
+ odr_set_stream(odr, m_file->fhandle, stream_write, 0);
+ z_GDU(odr, &gdu_req, 0, 0);
+ }