+
+static void show_raw_record_ok_binary(void *data, const char *buf, size_t sz)
+{
+ http_channel_observer_t obs = data;
+ struct http_channel *c = http_channel_observer_chan(obs);
+ struct http_response *rs = c->response;
+
+ http_remove_observer(obs);
+
+ wrbuf_write(c->wrbuf, buf, sz);
+ rs->payload = nmem_strdup(c->nmem, wrbuf_cstr(c->wrbuf));
+
+ rs->content_type = "application/octet-stream";
+ http_send_response(c);
+}
+
+
+void show_raw_reset(void *data, struct http_channel *c, void *data2)
+{
+ //struct client *client = data;
+ //client_show_raw_remove(client, data2);
+}
+
+static void cmd_record_ready(void *data);
+
+static void show_record(struct http_channel *c, struct http_session *s)
+{
+ struct http_response *rs = c->response;
+ struct http_request *rq = c->request;
+ struct record_cluster *rec, *prev_r, *next_r;
+ struct conf_service *service;
+ const char *idstr = http_argbyname(rq, "id");
+ const char *offsetstr = http_argbyname(rq, "offset");
+ const char *binarystr = http_argbyname(rq, "binary");
+ const char *checksumstr = http_argbyname(rq, "checksum");
+ const char *snippets = http_argbyname(rq, "snippets");
+ unsigned flags = (snippets && *snippets == '1') ? 3 : 1;
+
+ if (!s)
+ return;
+ service = s->psession->service;
+ if (!idstr)
+ {
+ error(rs, PAZPAR2_MISSING_PARAMETER, "id");
+ return;
+ }
+ wrbuf_rewind(c->wrbuf);
+ if (!(rec = show_single_start(s->psession, idstr, &prev_r, &next_r)))
+ {
+ if (session_active_clients(s->psession) == 0)
+ {
+ error(rs, PAZPAR2_RECORD_MISSING, idstr);
+ }
+ else if (session_set_watch(s->psession, SESSION_WATCH_RECORD,
+ cmd_record_ready, c, c) != 0)
+ {
+ error(rs, PAZPAR2_RECORD_MISSING, idstr);
+ }
+ return;
+ }
+ if (offsetstr || checksumstr)
+ {
+ const char *syntax = http_argbyname(rq, "syntax");
+ const char *esn = http_argbyname(rq, "esn");
+ int i;
+ struct record*r = rec->records;
+ int binary = 0;
+ const char *nativesyntax = http_argbyname(rq, "nativesyntax");
+
+ if (binarystr && *binarystr != '0')
+ binary = 1;
+
+ if (checksumstr)
+ {
+ unsigned v = strtoul(checksumstr, 0, 10);
+ for (i = 0; r; r = r->next)
+ if (v == r->checksum)
+ break;
+ if (!r)
+ error(rs, PAZPAR2_RECORD_FAIL, "no record");
+ }
+ else
+ {
+ int offset = atoi(offsetstr);
+ for (i = 0; i < offset && r; r = r->next, i++)
+ ;
+ if (!r)
+ error(rs, PAZPAR2_RECORD_FAIL, "no record at offset given");
+ }
+ if (r)
+ {
+ http_channel_observer_t obs =
+ http_add_observer(c, r->client, show_raw_reset);
+ int ret = client_show_raw_begin(r->client, r->position,
+ syntax, esn,
+ obs /* data */,
+ show_raw_record_error,
+ (binary ?
+ show_raw_record_ok_binary :
+ show_raw_record_ok),
+ (binary ? 1 : 0),
+ nativesyntax);
+ if (ret == -1)
+ {
+ http_remove_observer(obs);
+ error(rs, PAZPAR2_NO_SESSION, 0);
+ }
+ }
+ }
+ else
+ {
+ struct record *r;
+ response_open_command(c, "record");
+ wrbuf_puts(c->wrbuf, "\n <recid>");
+ wrbuf_xmlputs(c->wrbuf, rec->recid);
+ wrbuf_puts(c->wrbuf, "</recid>\n");
+ if (prev_r)
+ {
+ wrbuf_puts(c->wrbuf, " <prevrecid>");
+ wrbuf_xmlputs(c->wrbuf, prev_r->recid);
+ wrbuf_puts(c->wrbuf, "</prevrecid>\n");
+ }
+ if (next_r)
+ {
+ wrbuf_puts(c->wrbuf, " <nextrecid>");
+ wrbuf_xmlputs(c->wrbuf, next_r->recid);
+ wrbuf_puts(c->wrbuf, "</nextrecid>\n");
+ }
+ wrbuf_printf(c->wrbuf, " <activeclients>%d</activeclients>\n",
+ session_active_clients(s->psession));
+ write_metadata(c->wrbuf, service, rec->metadata, flags, 1);
+ for (r = rec->records; r; r = r->next)
+ write_subrecord(r, c->wrbuf, service, flags, 2);
+ response_close(c, "record");
+ }
+ show_single_stop(s->psession, rec);
+}
+
+static void cmd_record_ready(void *data)
+{
+ struct http_channel *c = (struct http_channel *) data;
+ struct http_session *s = locate_session(c);
+ if (s)
+ {
+ session_log(s->psession, c->http_sessions->log_level,
+ "record watch released");
+ show_record(c, s);
+ release_session(c, s);
+ }
+}
+
+static void cmd_record(struct http_channel *c)
+{
+ struct http_session *s = locate_session(c);
+ if (s)
+ {
+ show_record(c, s);
+ release_session(c, s);
+ }
+}
+
+
+static void show_records(struct http_channel *c, struct http_session *s,
+ int active)