+ http_sessions_t http_sessions = s->http_sessions;
+
+ yaz_log(YLOG_LOG, "%p HTTP session destroy %u", s, s->session_id);
+ yaz_mutex_enter(http_sessions->mutex);
+
+ /* only if http_session destroy was already called, we will allow it
+ to be destroyed */
+ if (s->destroy_counter != s->activity_counter)
+ must_destroy = 0;
+
+ s->destroy_counter = s->activity_counter = 0;
+ if (must_destroy)
+ {
+ struct http_session **p = 0;
+ for (p = &http_sessions->session_list; *p; p = &(*p)->next)
+ if (*p == s)
+ {
+ *p = (*p)->next;
+ break;
+ }
+ }
+ yaz_mutex_leave(http_sessions->mutex);
+ if (must_destroy)
+ { /* destroying for real */
+ yaz_log(YLOG_LOG, "%p HTTP session destroying. session id %u", s, s->session_id); iochan_destroy(s->timeout_iochan);
+ destroy_session(s->psession);
+ nmem_destroy(s->nmem);
+ }
+ else {
+ yaz_log(YLOG_DEBUG, "%p HTTP Session. Active clients on session %u. Waiting for new timeout.", s, s->session_id);
+ }
+
+}
+
+static const char *get_msg(enum pazpar2_error_code code)
+{
+ struct pazpar2_error_msg {
+ enum pazpar2_error_code code;
+ const char *msg;
+ };
+ static const struct pazpar2_error_msg ar[] = {
+ { PAZPAR2_NO_SESSION, "Session does not exist or it has expired"},
+ { PAZPAR2_MISSING_PARAMETER, "Missing parameter"},
+ { PAZPAR2_MALFORMED_PARAMETER_VALUE, "Malformed parameter value"},
+ { PAZPAR2_MALFORMED_PARAMETER_ENCODING, "Malformed parameter encoding"},
+ { PAZPAR2_MALFORMED_SETTING, "Malformed setting argument"},
+ { PAZPAR2_HITCOUNTS_FAILED, "Failed to retrieve hitcounts"},
+ { PAZPAR2_RECORD_MISSING, "Record missing"},
+ { PAZPAR2_NO_TARGETS, "No targets"},
+ { PAZPAR2_CONFIG_TARGET, "Target cannot be configured"},
+ { PAZPAR2_RECORD_FAIL, "Record command failed"},
+ { PAZPAR2_NOT_IMPLEMENTED, "Not implemented"},
+ { PAZPAR2_NO_SERVICE, "No service"},
+ { PAZPAR2_LAST_ERROR, "Last error"},
+ { 0, 0 }
+ };
+ int i = 0;
+ while (ar[i].msg)
+ {
+ if (code == ar[i].code)
+ return ar[i].msg;
+ i++;
+ }
+ return "No error";