New function ZOOM_connection_error_x.
Possible compatibility problems with earlier versions marked with '*'.
+For ZOOM connection, the options targetImplementation{Id,Name,Version}
+are set when Init Response is received.
+
+New function ZOOM_connection_error_x similar to ZOOM_connection_error
+but returns diagnostic set as well.
+
New function yaz_strerror which is a portable wrapper for
strerror/strerror_r/GetLastMessage.
-<!-- $Id: zoom.xml,v 1.20 2002-09-25 20:32:53 adam Exp $ -->
+<!-- $Id: zoom.xml,v 1.21 2002-12-09 23:32:29 adam Exp $ -->
<chapter id="zoom"><title>Building clients with ZOOM</title>
-
<para>
&zoom; is an acronym for 'Z39.50 Object-Orientation Model' and is
an initiative started by Mike Taylor (Mike is from the UK, which
<ulink url="http://zoom.z3950.org/">ZOOM web-site</ulink> for
more information.
</para>
-
+
<para>
In order to fully understand this chapter you should read and
try the example programs <literal>zoomtst1.c</literal>,
<literal>zoomtst2.c</literal>, .. in the <literal>zoom</literal>
directory.
</para>
-
+
<para>
The C language misses features found in object oriented languages
such as C++, Java, etc. For example, you'll have to manually,
<para>The Connection object is a session with a target.
</para>
<synopsis>
- #include <yaz/zoom.h>
+ #include <yaz/zoom.h>
- ZOOM_connection ZOOM_connection_new (const char *host, int portnum);
+ ZOOM_connection ZOOM_connection_new (const char *host, int portnum);
- ZOOM_connection ZOOM_connection_create (ZOOM_options options);
-
- void ZOOM_connection_connect(ZOOM_connection c, const char *host,
+ ZOOM_connection ZOOM_connection_create (ZOOM_options options);
+
+ void ZOOM_connection_connect(ZOOM_connection c, const char *host,
int portnum);
- void ZOOM_connection_destroy (ZOOM_connection c);
+ void ZOOM_connection_destroy (ZOOM_connection c);
</synopsis>
<para>
Connection objects are created with either function
The <function>ZOOM_connection_option_set</function> allows you to
set an option given by <parameter>key</parameter> to the value
<parameter>value</parameter> for the connection.
- Function <function>ZOOM_connection_option_get</function> returns
+ Function <function>ZOOM_connection_option_get</function> returns
the value for an option given by <parameter>key</parameter>.
</para>
<table frame="top"><title>ZOOM Connection Options</title>
</entry><entry>none</entry></row>
<row><entry>
pass</entry><entry>Authentication password
- </entry><entry>none</entry></row>
+ </entry><entry>none</entry></row>
<row><entry>
host</entry><entry>Target host. This setting is "read-only".
It's automatically set internally when connecting to a target.
<row><entry>
charset</entry><entry> Character set for negotiation.
</entry><entry>none</entry></row>
+ <row><entry>
+ targetImplementationId</entry><entry> Implementation ID of target.
+ </entry><entry>none</entry></row>
+ <row><entry>
+ targetImplementationName</entry><entry> Implementation Name of target.
+ </entry><entry>none</entry></row>
+ <row><entry>
+ targetImplementationVersion</entry><entry> Implementation Version
+ of target.
+ </entry><entry>none</entry></row>
</tbody>
</tgroup>
</table>
</para>
<synopsis>
int ZOOM_connection_error (ZOOM_connection c, const char **cp,
- const char **addinfo);
+ const char **addinfo);
+ int ZOOM_connection_error_x (ZOOM_connection c, const char **cp,
+ const char **addinfo, const char **dset);
</synopsis>
<para>
- Use <function>ZOOM_connection_error</function> to check for
+ Function <function>ZOOM_connection_error</function> checks for
errors for the last operation(s) performed. The function returns
zero if no errors occurred; non-zero otherwise indicating the error.
Pointers <parameter>cp</parameter> and <parameter>addinfo</parameter>
holds messages for the error and additional-info if passed as
- non-<literal>NULL</literal>.
+ non-<literal>NULL</literal>. Function
+ <function>ZOOM_connection_error_x</function> is an extended version
+ of <function>ZOOM_connection_error</function> that is capable of
+ returning name of diagnostic set in <parameter>dset</parameter>.
</para>
<sect2><title>Protocol behavior</title>
<para>
/*
* Public header for ZOOM C.
- * $Id: zoom.h,v 1.14 2002-11-30 22:30:51 mike Exp $
+ * $Id: zoom.h,v 1.15 2002-12-09 23:32:29 adam Exp $
*/
#include <yaz/yconfig.h>
ZOOM_connection_error (ZOOM_connection c, const char **cp,
const char **addinfo);
+ZOOM_API(int)
+ZOOM_connection_error_x (ZOOM_connection c, const char **cp,
+ const char **addinfo, const char **diagset);
+
/* returns error code */
ZOOM_API(int)
ZOOM_connection_errcode (ZOOM_connection c);
* Copyright (c) 1995-2002, Index Data
* See the file LICENSE for details.
*
- * $Id: marcdisp.c,v 1.24 2002-12-03 10:03:27 adam Exp $
+ * $Id: marcdisp.c,v 1.25 2002-12-09 23:32:29 adam Exp $
*/
#if HAVE_CONFIG_H
case YAZ_MARC_MARCXML:
wrbuf_printf(
wr,
- "<collection xmlns=\"http://www.loc.gov/MARC21/slim\">\n"
- " <record>\n"
- " <leader>%.24s</leader>\n", buf);
+ "<record xmlns=\"http://www.loc.gov/MARC21/slim\">\n"
+ " <leader>%.24s</leader>\n", buf);
break;
}
}
break;
case YAZ_MARC_MARCXML:
if (identifier_flag)
- wrbuf_printf (wr, " <datafield tag=\"%s\"", tag);
+ wrbuf_printf (wr, " <datafield tag=\"%s\"", tag);
else
- wrbuf_printf (wr, " <controlfield tag=\"%s\"", tag);
+ wrbuf_printf (wr, " <controlfield tag=\"%s\"", tag);
}
if (identifier_flag)
wrbuf_puts (wr, "\">");
break;
case YAZ_MARC_MARCXML:
- wrbuf_puts (wr, " <subfield code=\"");
+ wrbuf_puts (wr, " <subfield code=\"");
for (j = 1; j<identifier_length; j++, i++)
wrbuf_putc (wr, buf[i]);
wrbuf_puts (wr, "\">");
break;
case YAZ_MARC_MARCXML:
if (identifier_flag)
- wrbuf_puts (wr, " </datafield>\n");
+ wrbuf_puts (wr, " </datafield>\n");
else
- wrbuf_puts (wr, " </controlfield>\n");
+ wrbuf_puts (wr, " </controlfield>\n");
break;
}
}
wrbuf_puts (wr, "</oai_marc>\n");
break;
case YAZ_MARC_MARCXML:
- wrbuf_puts (wr, " </record>\n</collection>\n");
+ wrbuf_puts (wr, "</record>\n");
break;
}
return record_length;
/*
- * $Id: zoomtst2.c,v 1.4 2002-09-24 08:00:32 adam Exp $
+ * $Id: zoomtst2.c,v 1.5 2002-12-09 23:32:29 adam Exp $
*
* Asynchronous single-target client performing search (no retrieval)
*/
ZOOM_connection z;
ZOOM_resultset r;
int error;
- const char *errmsg, *addinfo;
+ const char *errmsg, *addinfo, *diagset;
if (argc < 3)
{
;
/* see if any error occurred */
- if ((error = ZOOM_connection_error(z, &errmsg, &addinfo)))
+ if ((error = ZOOM_connection_error_x(z, &errmsg, &addinfo, &diagset)))
{
- fprintf (stderr, "Error: %s (%d) %s\n", errmsg, error, addinfo);
+ fprintf (stderr, "Error: %s: %s (%d) %s\n", diagset, errmsg, error,
+ addinfo);
exit (2);
}
else /* OK print hit count */
/*
- * $Id: zoom-c.c,v 1.9 2002-12-03 10:03:27 adam Exp $
+ * Copyright (c) 2000-2002, Index Data
+ * See the file LICENSE for details.
+ *
+ * $Id: zoom-c.c,v 1.10 2002-12-09 23:32:29 adam Exp $
*
* ZOOM layer for C, connections, result sets, queries.
*/
return event;
}
+static void set_bib1_error (ZOOM_connection c, int error)
+{
+ xfree (c->addinfo);
+ c->addinfo = 0;
+ c->error = error;
+ c->diagset = "Bib-1";
+}
+
static void clear_error (ZOOM_connection c)
{
case ZOOM_ERROR_INTERNAL:
break;
default:
- c->error = ZOOM_ERROR_NONE;
- xfree (c->addinfo);
- c->addinfo = 0;
+ set_bib1_error(c, ZOOM_ERROR_NONE);
}
}
c->mask = 0;
c->reconnect_ok = 0;
c->state = STATE_IDLE;
- c->error = ZOOM_ERROR_NONE;
c->addinfo = 0;
+ set_bib1_error(c, ZOOM_ERROR_NONE);
c->buf_in = 0;
c->len_in = 0;
c->buf_out = 0;
c->async = ZOOM_options_get_bool (c->options, "async", 0);
- c->error = ZOOM_ERROR_NONE;
+ set_bib1_error(c, ZOOM_ERROR_NONE);
task = ZOOM_connection_add_task (c, ZOOM_TASK_CONNECT);
}
}
c->state = STATE_IDLE;
- c->error = ZOOM_ERROR_CONNECT;
+ set_bib1_error(c, ZOOM_ERROR_CONNECT);
return zoom_complete;
}
odr_destroy(odr_pr);
}
yaz_log (LOG_DEBUG, "encoding failed");
- c->error = ZOOM_ERROR_ENCODE;
+ set_bib1_error(c, ZOOM_ERROR_ENCODE);
odr_reset(out);
return -1;
}
static void response_diag (ZOOM_connection c, Z_DiagRec *p)
{
+ int oclass;
Z_DefaultDiagFormat *r;
char *addinfo = 0;
c->addinfo = 0;
if (p->which != Z_DiagRec_defaultFormat)
{
- c->error = ZOOM_ERROR_DECODE;
+ set_bib1_error(c, ZOOM_ERROR_DECODE);
return;
}
r = p->u.defaultFormat;
+ c->diagset = yaz_z3950oid_to_str(r->diagnosticSetId, &oclass);
+
switch (r->which)
{
case Z_DefaultDiagFormat_v2Addinfo:
if (sr->u.multipleNonSurDiagnostics->num_diagRecs >= 1)
response_diag(c, sr->u.multipleNonSurDiagnostics->diagRecs[0]);
else
- c->error = ZOOM_ERROR_DECODE;
+ set_bib1_error(c, ZOOM_ERROR_DECODE);
}
else
{
else if (present_phase)
{
/* present response and we didn't get any records! */
- c->error = ZOOM_ERROR_DECODE;
+ set_bib1_error(c, ZOOM_ERROR_DECODE);
}
}
}
{
case Z_APDU_initResponse:
initrs = apdu->u.initResponse;
+ ZOOM_connection_option_set(c, "targetImplementationId",
+ initrs->implementationId ?
+ initrs->implementationId : "");
+ ZOOM_connection_option_set(c, "targetImplementationName",
+ initrs->implementationName ?
+ initrs->implementationName : "");
+ ZOOM_connection_option_set(c, "targetImplementationVersion",
+ initrs->implementationVersion ?
+ initrs->implementationVersion : "");
if (!*initrs->result)
{
- c->error = ZOOM_ERROR_INIT;
+ set_bib1_error(c, ZOOM_ERROR_INIT);
}
else
{
}
else
{
- c->error = ZOOM_ERROR_CONNECTION_LOST;
+ set_bib1_error(c, ZOOM_ERROR_CONNECTION_LOST);
do_close(c);
}
break;
default:
- c->error = ZOOM_ERROR_DECODE;
+ set_bib1_error(c, ZOOM_ERROR_DECODE);
do_close(c);
}
}
ZOOM_connection_put_event (c, event);
if (!z_APDU (c->odr_in, &apdu, 0, 0))
{
- c->error = ZOOM_ERROR_DECODE;
+ set_bib1_error(c, ZOOM_ERROR_DECODE);
do_close (c);
}
else
return zoom_complete;
}
if (c->state == STATE_CONNECTING)
- c->error = ZOOM_ERROR_CONNECT;
+ set_bib1_error(c, ZOOM_ERROR_CONNECT);
else
- c->error = ZOOM_ERROR_CONNECTION_LOST;
+ set_bib1_error(c, ZOOM_ERROR_CONNECTION_LOST);
do_close (c);
return zoom_complete;
}
}
ZOOM_API(int)
-ZOOM_connection_error (ZOOM_connection c, const char **cp,
- const char **addinfo)
+ZOOM_connection_error_x (ZOOM_connection c, const char **cp,
+ const char **addinfo, const char **diagset)
{
int error = c->error;
if (cp)
*cp = ZOOM_diag_str(error);
}
if (addinfo)
- {
- if (c->addinfo)
- *addinfo = c->addinfo;
- else
- *addinfo = "";
- }
+ *addinfo = c->addinfo ? c->addinfo : "";
+ if (diagset)
+ *diagset = c->diagset ? c->diagset : "";
return c->error;
}
+ZOOM_API(int)
+ZOOM_connection_error (ZOOM_connection c, const char **cp,
+ const char **addinfo)
+{
+ return ZOOM_connection_error_x(c, cp, addinfo, 0);
+}
+
static int ZOOM_connection_do_io(ZOOM_connection c, int mask)
{
ZOOM_Event event = 0;
if (r == CS_NONE)
{
event = ZOOM_Event_create (ZOOM_EVENT_CONNECT);
- c->error = ZOOM_ERROR_CONNECT;
+ set_bib1_error(c, ZOOM_ERROR_CONNECT);
do_close (c);
ZOOM_connection_put_event (c, event);
}
}
else
{
- c->error = ZOOM_ERROR_CONNECT;
+ set_bib1_error(c, ZOOM_ERROR_CONNECT);
do_close (c);
ZOOM_connection_put_event (c, event);
}
{
ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_TIMEOUT);
/* timeout and this connection was waiting */
- c->error = ZOOM_ERROR_TIMEOUT;
+ set_bib1_error(c, ZOOM_ERROR_TIMEOUT);
do_close (c);
ZOOM_connection_put_event(c, event);
}
{
ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_TIMEOUT);
/* timeout and this connection was waiting */
- c->error = ZOOM_ERROR_TIMEOUT;
+ set_bib1_error(c, ZOOM_ERROR_TIMEOUT);
do_close (c);
yaz_log (LOG_DEBUG, "timeout");
ZOOM_connection_put_event(c, event);
/*
* Private C header for ZOOM C.
- * $Id: zoom-p.h,v 1.1 2002-09-16 18:45:14 adam Exp $
+ * $Id: zoom-p.h,v 1.2 2002-12-09 23:32:29 adam Exp $
*/
#include <yaz/proto.h>
#include <yaz/comstack.h>
char *host_port;
int error;
char *addinfo;
+ const char *diagset;
int state;
int mask;
int reconnect_ok;