--- 1.5.4 2011/03/08
-- Experiental support for DTIC DADS target
-- adds dads-pz2.xsl
-- Support for query_syntax (overrides the default for SRU | Z39.50)
-- Support for extraArgs (ZOOM "extraArgs" option) for targets
-- New commands: status-server and status-session
-
--- 1.5.3 2011/02/18
-- Fix for threaded runs:
-Client now have a copy of the database URL,
+--- 1.5.5 2011/03/28
+
+Fix memory leak that occurred for command=termlist&name=xtargets .
+
+Pazpar2 may save HTTP requests. Enabled by option -R.
+
+--- 1.5.4 2011/03/08
+
+Experimental support for DTIC DADS target. New dads-pz2.xsl.
+
+Support for query_syntax (overrides the default for SRU | Z39.50)
+
+Support for extraArgs (ZOOM "extraArgs" option) for targets
+
+New commands: status-server and status-session
+
+--- 1.5.3 2011/02/18
+
+Fix for threaded runs: Client now have a copy of the database URL,
which can used after the database has been release from the client.
-This makes the logging in the connection idle timeout of the client nicer (no NOURL)
-and should be thread-safe.
-- tmarc.xsl:
-Add journal-title-abbrev and full text.
-- cf.xsl
-New fields: isbn, issn, journaltitle, volume, issue
-- Fix for cmd=record before search.
-- Session Logging clean up
-- Fix: wrong termlist factor when maxrecs is different from 100.
-
--- 1.5.2 2011/01/18
-Fixes:
-- Missing pz:termlist_term_factor in settings.c messed up pz:preferred
-- Term factor is default enabled but can be diseabled by pz:termlist_term_factor=0
-
--- 1.5.1 2011/01/06
+This makes the logging in the connection idle timeout of the client nicer (no NOURL) and should be thread-safe.
+
+tmarc.xsl: Add journal-title-abbrev and full text.
+
+cf.xsl: new fields: isbn, issn, journaltitle, volume, issue
+
+Fix for cmd=record before search.
+
+Session Logging clean up.
+
+Fix wrong termlist factor when maxrecs is different from 100.
+
+--- 1.5.2 2011/01/18
+
+Fix missing pz:termlist_term_factor in settings.c messed up pz:preferred.
+Term factor is default enabled but can be diseabled by
+pz:termlist_term_factor=0
+
+--- 1.5.1 2011/01/06
Add scaling of facet count. Currently always enabled, needs fixing.
Allow user-defined info for target suffix. This has no meaning in
# Autoconf and automake setup
AC_PREREQ(2.60)
-AC_INIT([pazpar2],[1.5.4],[pazpar2-help@indexdata.dk])
+AC_INIT([pazpar2],[1.5.5],[pazpar2-help@indexdata.dk])
AC_CONFIG_HEADERS(src/config.h)
-pazpar2 (1.5.3-1indexata) unstable; urgency=low
+pazpar2 (1.5.5-1indexdata) unstable; urgency=low
- * Upstrem.
+ * Upstream.
+
+ -- Adam Dickmeiss <adam@indexdata.dk> Mon, 28 Mar 2011 15:42:06 +0200
+
+pazpar2 (1.5.3-1indexdata) unstable; urgency=low
+
+ * Upstream.
-- Dennis Schafroth <dennis@indexdata.com> Fri, 18 Feb 2011 12:26:12 +0100
On a Debian based Apache 2 system, the relevant modules can
be enabled with:
<screen>
- sudo a2enmod proxy_http
+ sudo a2enmod proxy_http proxy_balancer
</screen>
</para>
<arg choice="opt"><option>-h <replaceable>ip:port</replaceable></option></arg>
<arg choice="opt"><option>-l <replaceable>logfile</replaceable></option></arg>
<arg choice="opt"><option>-p <replaceable>pidfile</replaceable></option></arg>
+ <arg choice="opt"><option>-R <replaceable>recfile</replaceable></option></arg>
<arg choice="opt"><option>-t</option></arg>
<arg choice="opt"><option>-u <replaceable>uid</replaceable></option></arg>
<arg choice="opt"><option>-V</option></arg>
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>-R <replaceable>recfile</replaceable></option></term>
+ <listitem>
+ <para>
+ If this option is given, HTTP requests are logged to file named
+ <replaceable>recfile</replaceable>.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term><option>-t</option></term>
fi
fi
-echo "SESSIONS $MSG $SESSIONS ($CLIENTS) | $SESSIONS;$WARN_LEVEL;$CRIT_LEVEL "
+echo "SESSIONS $MSG $SESSIONS ($CLIENTS) [$VIRT,$VIRTUSE,$AREA,$ORDBLKS,$UORDBLKS,$FORDBLKS,$KEEPCOST,$HBLKS,$HBLKHD] | $SESSIONS;$WARN_LEVEL;$CRIT_LEVEL "
exit $rc
<xsl:apply-templates />
</xsl:template>
+ <xsl:template match="memory">
+ <xsl:apply-templates />
+ </xsl:template>
+
<xsl:template match="sessions">
<xsl:text>export SESSIONS=</xsl:text><xsl:value-of select="." />
</xsl:template>
<xsl:text>export RESULTSETS=</xsl:text><xsl:value-of select="." />
</xsl:template>
- <xsl:template match="*">
+ <xsl:template match="arena">
+ <xsl:text>AREA=</xsl:text><xsl:value-of select="." />
+ </xsl:template>
+
+ <xsl:template match="ordblks">
+ <xsl:text>ORDBLKS=</xsl:text><xsl:value-of select="." />
+ </xsl:template>
+
+ <xsl:template match="uordblks">
+ <xsl:text>UORDBLKS=</xsl:text><xsl:value-of select="." />
+ </xsl:template>
+
+ <xsl:template match="fordblks">
+ <xsl:text>FORDBLKS=</xsl:text><xsl:value-of select="." />
+ </xsl:template>
+
+ <xsl:template match="keepcost">
+ <xsl:text>KEEPCOST=</xsl:text><xsl:value-of select="." />
+ </xsl:template>
+
+ <xsl:template match="hblks">
+ <xsl:text>HBLKS=</xsl:text><xsl:value-of select="." />
+ </xsl:template>
+
+ <xsl:template match="hblkhd">
+ <xsl:text>HBLKHD=</xsl:text><xsl:value-of select="." />
</xsl:template>
+ <xsl:template match="virt">
+ <xsl:text>VIRT=</xsl:text><xsl:value-of select="." />
+ </xsl:template>
+
+ <xsl:template match="virtuse">
+ <xsl:text>VIRTUSE=</xsl:text><xsl:value-of select="." />
+ </xsl:template>
+
+ <xsl:template match="*" />
+
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
-<service id="perf_t" xmlns="http://www.indexdata.com/pazpar2/1.0">
+<service id="long" xmlns="http://www.indexdata.com/pazpar2/1.0">
<timeout session="600" z3950_operation="30" z3950_session="900"/>
<settings target="*">
<set target="localhost:9999/db01" name="pz:name" value="db01"/>
Summary: Metasearcher
Name: pazpar2
-Version: 1.5.3
-Release: 1
+Version: 1.5.5
+Release: 1indexdata
License: GPL
Group: Applications/Internet
Vendor: Index Data ApS <info@indexdata.dk>
yaz
pazpar2
+pazpar2_play
Makefile
Makefile.in
config.h
# This file is part of Pazpar2.
sbin_PROGRAMS = pazpar2
+noinst_PROGRAMS = pazpar2_play
EXTRA_DIST = pazpar2.rpm.init pazpar2.rpm.logrotate
pazpar2_SOURCES = pazpar2.c
pazpar2_LDADD = libpazpar2.a $(YAZLIB)
+pazpar2_play_SOURCES = pazpar2_play.c
+pazpar2_play_LDADD = $(YAZLIB)
+
test_sel_thread_SOURCES = test_sel_thread.c
test_sel_thread_LDADD = libpazpar2.a $(YAZLIB)
#include <config.h>
#endif
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
#include <stdio.h>
#ifdef WIN32
#include <winsock.h>
struct http_server
{
- struct http_buf *http_buf_freelist;
- int http_buf_freelist_count;
- int http_buf_freelist_max;
-
- struct http_channel *http_channel_freelist;
- int http_channel_freelist_count;
- int http_channel_freelist_max;
YAZ_MUTEX mutex;
int listener_socket;
int ref_count;
http_sessions_t http_sessions;
struct sockaddr_in *proxy_addr;
+ FILE *record_file;
};
struct http_channel_observer_s {
static struct http_buf *http_buf_create(http_server_t hs)
{
- struct http_buf *r = 0;
-
- yaz_mutex_enter(hs->mutex);
- if (hs->http_buf_freelist)
- {
- r = hs->http_buf_freelist;
- hs->http_buf_freelist = hs->http_buf_freelist->next;
- hs->http_buf_freelist_count--;
- }
- yaz_mutex_leave(hs->mutex);
- if (!r)
- r = xmalloc(sizeof(struct http_buf));
+ struct http_buf *r = xmalloc(sizeof(*r));
r->offset = 0;
r->len = 0;
r->next = 0;
static void http_buf_destroy(http_server_t hs, struct http_buf *b)
{
- yaz_mutex_enter(hs->mutex);
- if (hs->http_buf_freelist_max > 0 && hs->http_buf_freelist_count >= hs->http_buf_freelist_max) {
- xfree(b);
- while ((b = hs->http_buf_freelist)) {
- xfree(b);
- hs->http_buf_freelist = hs->http_buf_freelist->next;
- }
- hs->http_buf_freelist_count = 0;
- }
- else {
- b->next = hs->http_buf_freelist;
- hs->http_buf_freelist = b;
- hs->http_buf_freelist_count++;
-#if 0
- yaz_log(YLOG_DEBUG, "Free %d http buffers on server.", hs->http_buf_freelist_count);
-#endif
- }
- yaz_mutex_leave(hs->mutex);
+ xfree(b);
}
static void http_buf_destroy_queue(http_server_t hs, struct http_buf *b)
}
if (res <= 0)
{
+#if HAVE_SYS_TIME_H
+ if (hc->http_server->record_file)
+ {
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ fprintf(hc->http_server->record_file, "%lld %lld %lld 0\n",
+ (long long) tv.tv_sec, (long long) tv.tv_usec,
+ (long long) iochan_getfd(i));
+ }
+#endif
http_buf_destroy(hc->http_server, htbuf);
+ fflush(hc->http_server->record_file);
http_channel_destroy(i);
return;
}
return;
// we have a complete HTTP request
nmem_reset(hc->nmem);
+#if HAVE_SYS_TIME_H
+ if (hc->http_server->record_file)
+ {
+ struct timeval tv;
+ int sz = 0;
+ struct http_buf *hb;
+ for (hb = hc->iqueue; hb; hb = hb->next)
+ sz += hb->len;
+ gettimeofday(&tv, 0);
+ fprintf(hc->http_server->record_file, "%lld %lld %lld %d\n",
+ (long long) tv.tv_sec, (long long) tv.tv_usec,
+ (long long) iochan_getfd(i), sz);
+ for (hb = hc->iqueue; hb; hb = hb->next)
+ fwrite(hb->buf, 1, hb->len, hc->http_server->record_file);
+ }
+ #endif
if (!(hc->request = http_parse_request(hc, &hc->iqueue, reqlen)))
{
yaz_log(YLOG_WARN, "Failed to parse request");
http_server = s->http_server; /* save it for destroy (decref) */
- yaz_mutex_enter(s->http_server->mutex);
- if (s->http_server->http_channel_freelist_max > 0 && s->http_server->http_channel_freelist_count >= s->http_server->http_channel_freelist_max) {
- while ((s->next = s->http_server->http_channel_freelist)) {
- nmem_destroy(s->next->nmem);
- wrbuf_destroy(s->next->wrbuf);
- xfree(s->next);
- s->http_server->http_channel_freelist = s->http_server->http_channel_freelist->next;
- }
- s->http_server->http_channel_freelist_count = 0;
- }
- else {
- s->next = s->http_server->http_channel_freelist;
- s->http_server->http_channel_freelist = s;
- s->http_server->http_channel_freelist_count++;
- yaz_log(YLOG_DEBUG, "Free %d channels on server.", s->http_server->http_channel_freelist_count);
- }
- yaz_mutex_leave(s->http_server->mutex);
-
http_server_destroy(http_server);
#ifdef WIN32
close(iochan_getfd(i));
#endif
iochan_destroy(i);
+ nmem_destroy(s->nmem);
+ wrbuf_destroy(s->wrbuf);
+ xfree(s);
}
static struct http_channel *http_channel_create(http_server_t hs,
{
struct http_channel *r;
- yaz_mutex_enter(hs->mutex);
- r = hs->http_channel_freelist;
- if (r) {
- hs->http_channel_freelist = r->next;
- hs->http_channel_freelist_count--;
- }
- yaz_mutex_leave(hs->mutex);
+ r = xmalloc(sizeof(struct http_channel));
+ r->nmem = nmem_create();
+ r->wrbuf = wrbuf_alloc();
- if (r)
- {
- nmem_reset(r->nmem);
- wrbuf_rewind(r->wrbuf);
- }
- else
- {
- r = xmalloc(sizeof(struct http_channel));
- r->nmem = nmem_create();
- r->wrbuf = wrbuf_alloc();
- }
http_server_incref(hs);
r->http_server = hs;
r->http_sessions = hs->http_sessions;
}
/* Create a http-channel listener, syntax [host:]port */
-int http_init(const char *addr, struct conf_server *server)
+int http_init(const char *addr, struct conf_server *server,
+ const char *record_fname)
{
IOCHAN c;
int l;
int one = 1;
const char *pp;
short port;
+ FILE *record_file = 0;
yaz_log(YLOG_LOG, "HTTP listener %s", addr);
+
+ if (record_fname)
+ {
+ record_file = fopen(record_fname, "wb");
+ if (!record_file)
+ {
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "fopen %s", record_fname);
+ return 1;
+ }
+ }
+
memset(&myaddr, 0, sizeof myaddr);
myaddr.sin_family = AF_INET;
pp = strchr(addr, ':');
server->http_server = http_server_create();
+ server->http_server->record_file = record_file;
server->http_server->listener_socket = l;
c = iochan_create(l, http_accept, EVENT_INPUT | EVENT_EXCEPT, "http_server");
hs->ref_count = 1;
hs->http_sessions = 0;
- hs->http_channel_freelist = 0;
- hs->http_channel_freelist_count = 0;
- /* Disable max check */
- hs->http_channel_freelist_max = 0;
-
- hs->http_buf_freelist = 0;
- hs->http_buf_freelist_count = 0;
- /* Disable max check */
- hs->http_buf_freelist_max = 0;
+ hs->record_file = 0;
return hs;
}
if (r == 0)
{
- struct http_buf *b = hs->http_buf_freelist;
- struct http_channel *c = hs->http_channel_freelist;
- while (b)
- {
- struct http_buf *b_next = b->next;
- xfree(b);
- b = b_next;
- }
- while (c)
- {
- struct http_channel *c_next = c->next;
- nmem_destroy(c->nmem);
- wrbuf_destroy(c->wrbuf);
- xfree(c);
- c = c_next;
- }
http_sessions_destroy(hs->http_sessions);
xfree(hs->proxy_addr);
yaz_mutex_destroy(&hs->mutex);
+ if (hs->record_file)
+ fclose(hs->record_file);
xfree(hs);
}
}
void http_server_destroy(http_server_t hs);
void http_set_proxyaddr(const char *url, struct conf_server *ser);
-int http_init(const char *addr, struct conf_server *ser);
+int http_init(const char *addr, struct conf_server *ser,
+ const char *record_fname);
void http_close_server(struct conf_server *ser);
void http_addheader(struct http_response *r,
const char *name, const char *value);
#include "settings.h"
#include "client.h"
+#include <malloc.h>
+
+void print_meminfo(WRBUF wrbuf) {
+#ifdef __GNUC__
+ struct mallinfo minfo;
+ minfo = mallinfo();
+ wrbuf_printf(wrbuf, " <memory>\n"
+ " <arena>%d</arena>\n"
+ " <uordblks>%d</uordblks>\n"
+ " <fordblks>%d</fordblks>\n"
+ " <ordblks>%d</ordblks>\n"
+ " <keepcost>%d</keepcost>\n"
+ " <hblks>%d</hblks>\n"
+ " <hblkhd>%d</hblkhd>\n"
+ " <virt>%d</virt>\n"
+ " <virtuse>%d</virtuse>\n"
+ " </memory>\n",
+ minfo.arena, minfo.uordblks, minfo.fordblks,minfo.ordblks, minfo.keepcost, minfo.hblks, minfo.hblkhd, minfo.arena + minfo.hblkhd, minfo.uordblks + minfo.hblkhd);
+
+#endif
+}
+
+
// Update this when the protocol changes
#define PAZPAR2_PROTOCOL_VERSION "1"
unsigned int res;
seq++;
- if (global_parameters.debug_mode)
+ if (global_parameters.predictable_sessions)
res = seq;
else
{
wrbuf_printf(c->wrbuf, " <clients>%u</clients>\n", clients);
/* Only works if yaz has been compiled with enabling of this */
wrbuf_printf(c->wrbuf, " <resultsets>%u</resultsets>\n",resultsets);
+ print_meminfo(c->wrbuf);
/* TODO add all sessions status */
/* http_sessions_t http_sessions = c->http_sessions; */
if (settings && *settings == '1')
{
wrbuf_puts(c->wrbuf, "<settings>\n");
- wrbuf_puts(c->wrbuf, wrbuf_cstr(ht[i].settings_xml));
+ wrbuf_puts(c->wrbuf, ht[i].settings_xml);
wrbuf_puts(c->wrbuf, "</settings>\n");
}
wrbuf_puts(c->wrbuf, "</target>");
- wrbuf_destroy(ht[i].settings_xml);
}
wrbuf_puts(c->wrbuf, "</bytarget>");
struct parameters {
int dump_records;
int debug_mode;
+ int predictable_sessions;
};
extern struct parameters global_parameters;
#include <yaz/options.h>
#include <yaz/sc.h>
+// #define MTRACE
+#ifdef MTRACE
+#include <mcheck.h>
+#endif
+
static struct conf_config *sc_stop_config = 0;
void child_handler(void *data)
const char *uid = 0;
const char *listener_override = 0;
const char *config_fname = 0;
+ const char *record_fname = 0;
struct conf_config *config = 0;
int test_mode = 0;
yaz_log_init_prefix("pazpar2");
yaz_log_xml_errors(0, YLOG_WARN);
- while ((ret = options("dDf:h:l:p:tu:v:VX", argv, argc, &arg)) != -2)
+ while ((ret = options("dDf:h:l:p:R:tu:v:VX", argv, argc, &arg)) != -2)
{
switch (ret)
{
case 'p':
pidfile = arg;
break;
+ case 'R':
+ record_fname = arg;
+ global_parameters.predictable_sessions = 1;
+ break;
case 't':
test_mode = 1;
break;
show_version();
case 'X':
global_parameters.debug_mode++;
+ global_parameters.predictable_sessions = 1;
break;
default:
fprintf(stderr, "Usage: pazpar2\n"
" -h [host:]port Listener port\n"
" -l file Log to file\n"
" -p pidfile PID file\n"
+ " -R recfile HTTP recording file\n"
" -t Test configuration\n"
" -u uid Change user to uid\n"
" -V Show version\n"
"mode");
return 1;
}
- ret = config_start_listeners(config, listener_override);
+ ret = config_start_listeners(config, listener_override, record_fname);
if (ret)
return ret; /* error starting http listener */
{
int ret;
yaz_sc_t s = yaz_sc_create("pazpar2", "Pazpar2");
+
+#ifdef MTRACE
+ mtrace();
+#endif
ret = yaz_sc_program(s, argc, argv, sc_main, sc_stop);
yaz_sc_destroy(&s);
+
+#ifdef MTRACE
+ muntrace();
+#endif
+
+
exit(ret);
}
}
int config_start_listeners(struct conf_config *conf,
- const char *listener_override)
+ const char *listener_override,
+ const char *record_fname)
{
struct conf_server *ser;
wrbuf_printf(w, "%d", ser->port);
}
}
- r = http_init(wrbuf_cstr(w), ser);
+ r = http_init(wrbuf_cstr(w), ser, record_fname);
wrbuf_destroy(w);
if (r)
return -1;
void service_destroy(struct conf_service *service);
int config_start_listeners(struct conf_config *conf,
- const char *listener_override);
+ const char *listener_override,
+ const char *record_fname);
void config_stop_listeners(struct conf_config *conf);
--- /dev/null
+/* This file is part of Pazpar2.
+ Copyright (C) 2006-2011 Index Data
+
+Pazpar2 is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+Pazpar2 is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <time.h>
+#include <stdlib.h>
+#include <sys/select.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <yaz/options.h>
+#include <yaz/log.h>
+#include <yaz/xmalloc.h>
+
+struct con {
+ int fd;
+ long long id;
+ struct con *next;
+};
+
+
+static int run(FILE *inf, struct addrinfo *res)
+{
+ long long tv_sec0 = 0;
+ long long tv_usec0 = 0;
+ struct con *cons = 0;
+
+ while (1)
+ {
+ long long tv_sec1;
+ long long tv_usec1;
+ long long id;
+ int sz, r, c;
+ char req[100];
+ size_t i;
+ struct con **conp;
+ c = fgetc(inf);
+ if (c == EOF)
+ break;
+
+ for (i = 0; c != '\n' && i < (sizeof(req)-2); i++)
+ {
+ req[i] = c;
+ c = fgetc(inf);
+ }
+ req[i] = 0;
+ r = sscanf(req, "%lld %lld %lld %d", &tv_sec1, &tv_usec1, &id, &sz);
+ if (r != 4)
+ {
+ fprintf(stderr, "bad line %s\n", req);
+ return -1;
+ }
+ if (tv_sec0)
+ {
+ struct timeval spec;
+
+ spec.tv_sec = tv_sec1 - tv_sec0;
+ if (tv_usec0 > tv_usec1)
+ {
+ spec.tv_usec = 1000000 + tv_usec1 - tv_usec0;
+ spec.tv_sec--;
+ }
+ else
+ spec.tv_usec = tv_usec1 - tv_usec0;
+
+ select(0, 0, 0, 0, &spec);
+ }
+ tv_sec0 = tv_sec1;
+ tv_usec0 = tv_usec1;
+ for (conp = &cons; *conp; conp = &(*conp)->next)
+ if ((*conp)->id == id)
+ break;
+ if (!*conp)
+ {
+ struct addrinfo *rp;
+ int r, fd = -1;
+ for (rp = res; rp; rp = rp->ai_next)
+ {
+ fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+ if (fd != -1)
+ break;
+ }
+ if (fd == -1)
+ {
+ fprintf(stderr, "socket: cannot create\n");
+ return -1;
+ }
+ r = connect(fd, rp->ai_addr, rp->ai_addrlen);
+ if (r)
+ {
+ fprintf(stderr, "socket: cannot connect\n");
+ return -1;
+ }
+
+ *conp = xmalloc(sizeof(**conp));
+ (*conp)->id = id;
+ (*conp)->fd = fd;
+ (*conp)->next = 0;
+ }
+ if (sz == 0)
+ {
+ struct con *c = *conp;
+ *conp = c->next;
+ close(c->fd);
+ xfree(c);
+ }
+ else
+ {
+ size_t cnt = 0;
+ while (cnt < sz)
+ {
+ char buf[1024];
+ ssize_t w;
+ size_t r;
+ size_t toread = sz - cnt;
+
+ if (toread > sizeof(buf))
+ toread = sizeof(buf);
+ r = fread(buf, 1, toread, inf);
+ if (r != toread)
+ {
+ fprintf(stderr, "fread truncated. toread=%lld r=%lld\n",
+ (long long) toread, (long long) r);
+ return -1;
+ }
+ w = write((*conp)->fd, buf, toread);
+ if (w != toread)
+ {
+ fprintf(stderr, "write truncated\n");
+ return -1;
+ }
+ cnt += toread;
+ }
+ }
+ }
+ return 0;
+}
+
+static void usage(void)
+{
+ fprintf(stderr, "Usage: pazpar2_play infile host\n"
+ " -v level Set log level\n");
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+ char *arg;
+ char *host = 0;
+ const char *file = 0;
+ while ((ret = options("v:", argv, argc, &arg)) != -2)
+ {
+ switch (ret)
+ {
+ case 'v':
+ yaz_log_init_level(yaz_log_mask_str(arg));
+ break;
+ case 0:
+ if (!file)
+ file = arg;
+ else if (!host)
+ host = xstrdup(arg);
+ else
+ {
+ usage();
+ }
+ break;
+ default:
+ usage();
+ exit(1);
+ }
+ }
+ if (host && file)
+ {
+ char *port;
+ char *cp;
+ FILE *inf;
+
+ struct addrinfo hints, *res;
+ hints.ai_flags = 0;
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+ hints.ai_addrlen = 0;
+ hints.ai_addr = NULL;
+ hints.ai_canonname = NULL;
+ hints.ai_next = NULL;
+
+ cp = strchr(host, ':');
+ if (*cp)
+ {
+ *cp = 0;
+ port = cp+1;
+ }
+ else
+ {
+ port = "80";
+ }
+ if (getaddrinfo(host, port, &hints, &res))
+ {
+ fprintf(stderr, "cannot resolve %s:%s\n", host, port);
+ exit(1);
+ }
+
+ inf = fopen(file, "rb");
+ if (!inf)
+ {
+ fprintf(stderr, "cannot open %s\n", file);
+ exit(1);
+ }
+ run(inf, res);
+ fclose(inf);
+ }
+ else
+ usage();
+ return 0;
+}
+
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+
struct parameters global_parameters =
{
0, // dump_records
- 0 // debug_mode
+ 0, // debug_mode
+ 0, // predictable sessions
};
struct client_list {
res[*count].state = client_get_state_str(cl);
res[*count].connected = client_get_connection(cl) ? 1 : 0;
session_settings_dump(se, client_get_database(cl), w);
- res[*count].settings_xml = w;
+ res[*count].settings_xml = nmem_strdup(nmem, wrbuf_cstr(w));
+ wrbuf_destroy(w);
(*count)++;
}
session_leave(se);
int records;
const char *state;
int connected;
- WRBUF settings_xml;
+ char *settings_xml;
};
struct hitsbytarget *hitsbytarget(struct session *s, int *count, NMEM nmem);
VALGRINDLOG=${PREFIX}_valgrind.log
if test -n "$PAZPAR2_USE_VALGRIND"; then
- valgrind --leak-check=full --log-file=$VALGRINDLOG ../src/pazpar2 -X -l pazpar2.log -f ${CFG} >extra_pazpar2.log 2>&1 &
+ valgrind --num-callers=30 --show-reachable=yes --leak-check=full --log-file=$VALGRINDLOG ../src/pazpar2 -X -l pazpar2.log -f ${CFG} >extra_pazpar2.log 2>&1 &
elif test -n "$SKIP_PAZPAR2"; then
echo "Skipping pazpar2. Must already be running with correct config!!! "
else
</facet>
<service>
-
+ <timeout session="30" z3950_operation="20" z3950_session="40"/>
<metadata name="url" merge="unique"/>
<metadata name="title" brief="yes" sortkey="skiparticle" merge="longest" rank="6"/>
<metadata name="title-remainder" brief="yes" merge="longest" rank="5"/>
http://localhost:9763/search.pz2?session=1&command=show&start=0&number=1&sort=date:0
http://localhost:9763/search.pz2?session=1&command=show&start=0&number=1&sort=date:1
http://localhost:9763/search.pz2?session=1&command=termlist&name=author%2Csubject
-http://localhost:9763/search.pz2?session=1&command=show&start=0&number=1
\ No newline at end of file
+http://localhost:9763/search.pz2?session=1&command=show&start=0&number=1
+http://localhost:9763/search.pz2?session=1&command=termlist&name=xtargets
--- /dev/null
+<termlist>
+<activeclients>0</activeclients>
+<list name="xtargets">
+<term>
+<id>z3950.indexdata.com/marc</id>
+<name>Index Data MARC test server</name>
+<frequency>10</frequency>
+<state>Client_Idle</state>
+<diagnostic>0</diagnostic>
+</term>
+</list>
+</termlist>
DEBUG=0 # 0 for release, 1 for debug
USE_MANIFEST = 1 # Can be enabled Visual Studio 2005/2008
PACKAGE_NAME=pazpar2
-PACKAGE_VERSION=1.4.4
+PACKAGE_VERSION=1.5.5
# YAZ
YAZ_DIR=..\..\yaz