-</synopsis>
-
-<para>
-The <literal>configname</literal> of <literal>bend_initrequest</literal>
-is currently always set to "default-config". We haven't had
-use for putting anything special in the initrequest yet, but something
-might go there if the need arises (account/password info would be obvious).
-</para>
-
-<para>
-In general, the server frontend expects that the
-<literal>bend_*result</literal> pointer that you return is valid at
-least until the next call to a <literal>bend_* function</literal>.
-This applies to all of the functions described herein. The parameter
-structure passed to you in the call belongs to the server frontend, and
-you should not make assumptions about its contents after the current
-function call has completed. In other words, if you want to retain any
-of the contents of a request structure, you should copy them.
-</para>
-
-<para>
-The <literal>errcode</literal> should be zero if the initialization of
-the backend went well. Any other value will be interpreted as an error.
-The <literal>errstring</literal> isn't used in the current version, but one
-optin would be to stick it in the initResponse as a VisibleString.
-The <literal>handle</literal> is the most important parameter. It should
-be set to some value that uniquely identifies the current session to
-the backend implementation. It is used by the frontend server in any
-future calls to a backend function.
-The typical use is to set it to point to a dynamically allocated state
-structure that is private to your backend module.
-</para>
-
-<synopsis>
-bend_searchresult *bend_search(void *handle, bend_searchrequest *r,
- int *fd);
-bend_searchresult *bend_searchresponse(void *handle);
-
-typedef struct bend_searchrequest
-{
- char *setname; /* name to give to this set */
- int replace_set; /* replace set, if it already exists */
- int num_bases; /* number of databases in list */
- char **basenames; /* databases to search */
- Z_Query *query; /* query structure */
-} bend_searchrequest;
-
-typedef struct bend_searchresult
-{
- int hits; /* number of hits */
- int errcode; /* 0==OK */
- char *errstring; /* system error string or NULL */
-} bend_searchresult;
-</synopsis>
-
-<para>
-The first thing to notice about the search request interface (as well
-as all of the following requests), is that it consists of two separate
-functions. The idea is to provide a simple facility for
-asynchronous communication with the backend server. When a
-searchrequest comes in, the server frontend will fill out the
-<function>bend_searchrequest</function> tructure, and call the
-<function>bend_search</function> function/. The <literal>fd</literal>
-argument will point to an integer variable. If you are able to do
-asynchronous I/O with your database server, you should set
-<literal>*fd</literal> to the file descriptor you use for the
-communication, and return a null pointer.
-The server frontend will then <function>select()</function> on the
-<literal>*fd</literal>, and will call
-<function>bend_searchresult</function> when it sees that data is available.
-If you don't support asynchronous I/O, you should return a pointer to the
-<function>bend_searchresult</function> immediately, and leave
-<literal>*fd</literal> untouched. This construction is common to
-all of the <function>bend_</function> functions (except
-<function>bend_init</function>). Note that you can choose to support
-this facility in none, any, or all of the <function>bend_</function>
-functions, and you can respond differently on each request at run-time.
-The server frontend will adapt accordingly.
-</para>
-
-<para>
-The <function>bend_searchrequest</function> is a fairly close
-approximation of a protocol searchRequest PDU. The
-<literal>setname</literal> is the resultSetName from the protocol. You
-are required to establish a mapping between the set name and whatever
-your backend database likes to use. Similarly, the
-<literal>replace_set</literal> is a boolean value corresponding to the
-resultSetIndicator field in the protocol.
-<literal>Num_bases/basenames</literal> is a length of/array of character
-pointers to the database names provided by the client. The
-<literal>query</literal> is the full query structure as defined in the
-protocol ASN.1 specification. It can be either of the possible query
-types, and it's up to you to determine if you can handle the provided
-query type. Rather than reproduce the C interface here, we'll refer you
-to the structure definitions in the file
-<filename>include/yaz/proto.h</filename>. If you want to look at the
-attributeSetId OID of the RPN query, you can either match it against
-your own internal tables, or you can use the
-<literal>oid_getentbyoid</literal> function provided by &yaz;.
-</para>
-
-<para>
-The result structure contains a number of hits, and an
-<literal>errcode/errstring</literal> pair. If an error occurs
-during the search, or if you're unhappy with the request, you should
-set the errcode to a value from the BIB-1 diagnostic set. The value
-will then be returned to the user in a nonsurrogate diagnostic record
-in the response. The <literal>errstring</literal>, if provided, will
-go in the addinfo field. Look at the protocol definition for the
-defined error codes, and the suggested uses of the addinfo field.
-</para>
-
-<synopsis>
-bend_fetchresult *bend_fetch(void *handle, bend_fetchrequest *r,
- int *fd);
-bend_fetchresult *bend_fetchresponse(void *handle);
-
-typedef struct bend_fetchrequest
-{
- char *setname; /* set name */
- int number; /* record number */
- oid_value format;
-} bend_fetchrequest;
-
-typedef struct bend_fetchresult
-{
- char *basename; /* name of database that provided record */
- int len; /* length of record */
- char *record; /* record */
- int last_in_set; /* is it? */
- oid_value format;
- int errcode; /* 0==success */
- char *errstring; /* system error string or NULL */
-} bend_fetchresult;
-</synopsis>
-
-<note>
-<para>
-The <function>bend_fetchresponse()</function> function is not yet supported
-in this version of the software. Your implementation of
-<function>bend_fetch()</function> should always return a pointer to a
-<literal>bend_fetchresult</literal>.
-</para>
-</note>
-
-<para>
-The frontend server calls <function>bend_fetch</function> when it needs
-database records to fulfill a searchRequest or a presentRequest.
-The <literal>setname</literal> is simply the name of the result set
-that holds the reference to the desired record.
-The <literal>number</literal> is the offset into the set (with 1
-being the first record in the set). The <literal>format</literal> field
-is the record format requested by the client (See section
-<link linkend="oid">Object Identifiers</link>). The value
-<literal>VAL_NONE</literal> indicates that the client did not
-request a specific format. The <literal>stream</literal> argument
-is an &odr; stream which should be used for
-allocating space for structured data records. The stream will be reset when
-all records have been assembled, and the response package has been transmitted.
-For unstructured data, the backend is responsible for maintaining a static
-or dynamic buffer for the record between calls.
-</para>
-
-<para>
-In the result structure, the <literal>basename</literal> is the name of the
-database that holds the
-record. <literal>len</literal> is the length of the record returned, in
-bytes, and <literal>record</literal> is a pointer to the record.
-<literal>Last_in_set</literal> should be nonzero only if the record
-returned is the last one in the given result set. <literal>errcode</literal>
-and <literal>errstring</literal>, if given, will currently be
-interpreted as a global error pertaining to the set, and will be returned in a
-nonSurrogateDiagnostic.
-</para>
-
-<note>
-<para>
-This is silly. Add a flag to say which is which.
-</para>
-</note>
-
-<para>
-If the <literal>len</literal> field has the value -1, then
-<literal>record</literal> is assumed to point to a constructed data
-type. The <literal>format</literal> field will be used to determine
-which encoder should be used to serialize the data.
-</para>
-
-<note>
-<para>
-If your backend generates structured records, it should use
-<function>odr_malloc()</function> on the provided stream for allocating
-data: This allows the frontend server to keep track of the record sizes.
-</para>
-</note>
-
-<para>
-The <literal>format</literal> field is mapped to an object identifier
-in the direct reference of the resulting EXTERNAL representation of the record.
-</para>
-
-<note>
-<para>
-The current version of &yaz; only supports the direct reference mode.
-</para>
-</note>
-
-<synopsis>
-bend_deleteresult *bend_delete(void *handle, bend_deleterequest *r,
- int *fd);
-bend_deleteresult *bend_deleteresponse(void *handle);
-
-typedef struct bend_deleterequest
-{
- char *setname;
-} bend_deleterequest;
-
-typedef struct bend_deleteresult
-{
- int errcode; /* 0==success */
- char *errstring; /* system error string or NULL */
-} bend_deleteresult;
-</synopsis>
-
-<note>
-<para>
-The "delete" function is not yet supported in this version of
-the software.
-</para>
-</note>
-
-<note>
-<para>
-The delete set function definition is rather primitive, mostly because we
-have had no practical need for it as of yet. If someone wants
-to provide a full delete service, we'd be happy to add the
-extra parameters that are required. Are there clients out there
-that will actually delete sets they no longer need?
-</para>
-</note>
-
-<synopsis>
-bend_scanresult *bend_scan(void *handle, bend_scanrequest *r,
- int *fd);
-bend_scanresult *bend_scanresponse(void *handle);
-
-typedef struct bend_scanrequest
-{
- int num_bases; /* number of elements in databaselist */
+ </synopsis>
+
+ <para>
+ In general, the server frontend expects that the
+ <literal>bend_*result</literal> pointer that you return is valid at
+ least until the next call to a <literal>bend_* function</literal>.
+ This applies to all of the functions described herein. The parameter
+ structure passed to you in the call belongs to the server frontend, and
+ you should not make assumptions about its contents after the current
+ function call has completed. In other words, if you want to retain any
+ of the contents of a request structure, you should copy them.
+ </para>
+
+ <para>
+ The <literal>errcode</literal> should be zero if the initialization of
+ the backend went well. Any other value will be interpreted as an error.
+ The <literal>errstring</literal> isn't used in the current version, but
+ one option would be to stick it in the initResponse as a VisibleString.
+ The <literal>handle</literal> is the most important parameter. It should
+ be set to some value that uniquely identifies the current session to
+ the backend implementation. It is used by the frontend server in any
+ future calls to a backend function.
+ The typical use is to set it to point to a dynamically allocated state
+ structure that is private to your backend module.
+ </para>
+
+ <para>
+ The <literal>auth</literal> member holds the authentication information
+ part of the Z39.50 Initialize Request. Interpret this if your serves
+ requires authentication.
+ </para>
+
+ <para>
+ The members <literal>peer_name</literal>,
+ <literal>implementation_id</literal>,
+ <literal>implementation_name</literal> and
+ <literal>implementation_version</literal> holds
+ DNS of client, ID of implementor, name
+ of client (Z39.50) implementation - and version.
+ </para>
+
+ <para>
+ The <literal>bend_</literal> - members are set to NULL when
+ <function>bend_init</function> is called. Modify the pointers by
+ setting them to point to backend functions.
+ </para>
+
+ </sect2>
+
+ <sect2><title>Search and retrieve</title>
+
+ <para>We now describe the handlers that are required to support search -
+ and retrieve. You must support two functions - one for search - and one
+ for fetch (retrieval of one record). If desirable you can provide a
+ third handler which is called when a present request is received which
+ allows you to optimize retrieval of multiple-records.
+ </para>
+
+ <synopsis>
+int (*bend_search) (void *handle, bend_search_rr *rr);
+
+typedef struct {
+ char *setname; /* name to give to this set */
+ int replace_set; /* replace set, if it already exists */
+ int num_bases; /* number of databases in list */
+ char **basenames; /* databases to search */
+ Z_ReferenceId *referenceId;/* reference ID */
+ Z_Query *query; /* query structure */
+ ODR stream; /* encode stream */
+ ODR decode; /* decode stream */
+ ODR print; /* print stream */
+
+ bend_request request;
+ bend_association association;
+ int *fd;
+ int hits; /* number of hits */
+ int errcode; /* 0==OK */
+ char *errstring; /* system error string or NULL */
+ Z_OtherInformation *search_info;
+} bend_search_rr;
+ </synopsis>
+
+ <para>
+ The <function>bend_search</function> handler is a fairly close
+ approximation of a protocol Z39.50 Search Request - and Response PDUs
+ The <literal>setname</literal> is the resultSetName from the protocol.
+ You are required to establish a mapping between the set name and whatever
+ your backend database likes to use.
+ Similarly, the <literal>replace_set</literal> is a boolean value
+ corresponding to the resultSetIndicator field in the protocol.
+ <literal>num_bases/basenames</literal> is a length of/array of character
+ pointers to the database names provided by the client.
+ The <literal>query</literal> is the full query structure as defined in
+ the protocol ASN.1 specification.
+ It can be either of the possible query types, and it's up to you to
+ determine if you can handle the provided query type.
+ Rather than reproduce the C interface here, we'll refer you to the
+ structure definitions in the file
+ <filename>include/yaz/z-core.h</filename>. If you want to look at the
+ attributeSetId OID of the RPN query, you can either match it against
+ your own internal tables, or you can use the
+ <literal>oid_getentbyoid</literal> function provided by &yaz;.
+ </para>
+
+ <para>
+ The structure contains a number of hits, and an
+ <literal>errcode/errstring</literal> pair. If an error occurs
+ during the search, or if you're unhappy with the request, you should
+ set the errcode to a value from the BIB-1 diagnostic set. The value
+ will then be returned to the user in a nonsurrogate diagnostic record
+ in the response. The <literal>errstring</literal>, if provided, will
+ go in the addinfo field. Look at the protocol definition for the
+ defined error codes, and the suggested uses of the addinfo field.
+ </para>
+
+ <para>
+ The <function>bend_search</function> handler is also called when
+ the frontend server receives a SRW/SRU SearchRetrieveRequest.
+ For SRW/SRU, a CQL query is usually provided by the client.
+ The CQL query is available as part of <literal>Z_Query</literal>
+ structure (note that CQL is now part of Z39.50 via an external).
+ To support CQL in existing implementations that only do Type-1,
+ we refer to the CQL-to-PQF tool described
+ <link linkend="tools.cql.pqf">here</link>.
+ </para>
+
+ <para>
+ To maintain backwards compatibility, the frontend server
+ of yaz always assume that error codes are BIB-1 diagnostics.
+ For SRW/SRU operation, a Bib-1 diagnostic code is mapped to
+ SRW/SRU diagnostic.
+ </para>
+
+ <synopsis>
+int (*bend_fetch) (void *handle, bend_fetch_rr *rr);
+
+typedef struct bend_fetch_rr {
+ char *setname; /* set name */
+ int number; /* record number */
+ Z_ReferenceId *referenceId;/* reference ID */
+ oid_value request_format; /* One of the CLASS_RECSYN members */
+ int *request_format_raw; /* same as above (raw OID) */
+ Z_RecordComposition *comp; /* Formatting instructions */
+ ODR stream; /* encoding stream - memory source if req */
+ ODR print; /* printing stream */
+
+ char *basename; /* name of database that provided record */
+ int len; /* length of record or -1 if structured */
+ char *record; /* record */
+ int last_in_set; /* is it? */
+ oid_value output_format; /* format */
+ int *output_format_raw; /* used instead of above if not-null */
+ int errcode; /* 0==success */
+ char *errstring; /* system error string or NULL */
+ int surrogate_flag; /* surrogate diagnostic */
+ char *schema; /* string record schema input/output */
+} bend_fetch_rr;
+ </synopsis>
+
+ <para>
+ The frontend server calls the <function>bend_fetch</function> handler
+ when it needs database records to fulfill a Z39.50 Search Request, a
+ Z39.50 Present Request or a SRW SearchRetrieveRequest.
+ The <literal>setname</literal> is simply the name of the result set
+ that holds the reference to the desired record.
+ The <literal>number</literal> is the offset into the set (with 1
+ being the first record in the set). The <literal>format</literal> field
+ is the record format requested by the client (See
+ <xref linkend="asn.oid"/>).
+ The value <literal>VAL_NONE</literal> indicates that the client did
+ not request a specific format. The <literal>stream</literal> argument
+ is an &odr; stream which should be used for
+ allocating space for structured data records.
+ The stream will be reset when all records have been assembled, and
+ the response package has been transmitted.
+ For unstructured data, the backend is responsible for maintaining a
+ static or dynamic buffer for the record between calls.
+ </para>
+
+ <para>
+ If a SRW/SRU SearchRetrieveRequest is received by the frontend server,
+ the <literal>referenceId</literal> is NULL and the
+ <literal>request_format</literal> (transfer syntax) is XML (OID name
+ <literal>VAL_TEXT_XML</literal>).
+ The schema for SRW/SRU is stored in both the
+ <literal>Z_RecordComposition</literal>
+ structure and <literal>schema</literal> (simple string).
+ </para>
+
+ <para>
+ In the structure, the <literal>basename</literal> is the name of the
+ database that holds the
+ record. <literal>len</literal> is the length of the record returned, in
+ bytes, and <literal>record</literal> is a pointer to the record.
+ <literal>last_in_set</literal> should be nonzero only if the record
+ returned is the last one in the given result set.
+ <literal>errcode</literal> and <literal>errstring</literal>, if
+ given, will be interpreted as a global error pertaining to the
+ set, and will be returned in a non-surrogate-diagnostic.
+ If you wish to return the error as a surrogate-diagnostic
+ (local error) you can do this by setting
+ <literal>surrogate_flag</literal> to 1 also.
+ </para>
+
+ <para>
+ If the <literal>len</literal> field has the value -1, then
+ <literal>record</literal> is assumed to point to a constructed data
+ type. The <literal>format</literal> field will be used to determine
+ which encoder should be used to serialize the data.
+ </para>
+
+ <note>
+ <para>
+ If your backend generates structured records, it should use
+ <function>odr_malloc()</function> on the provided stream for allocating
+ data: This allows the frontend server to keep track of the record sizes.
+ </para>
+ </note>
+
+ <para>
+ The <literal>format</literal> field is mapped to an object identifier
+ in the direct reference of the resulting EXTERNAL representation
+ of the record.
+ </para>
+
+ <note>
+ <para>
+ The current version of &yaz; only supports the direct reference mode.
+ </para>
+ </note>
+
+ <synopsis>
+int (*bend_present) (void *handle, bend_present_rr *rr);
+
+typedef struct {
+ char *setname; /* set name */
+ int start;
+ int number; /* record number */
+ oid_value format; /* One of the CLASS_RECSYN members */
+ Z_ReferenceId *referenceId;/* reference ID */
+ Z_RecordComposition *comp; /* Formatting instructions */
+ ODR stream; /* encoding stream */
+ ODR print; /* printing stream */
+ bend_request request;
+ bend_association association;
+
+ int hits; /* number of hits */
+ int errcode; /* 0==OK */
+ char *errstring; /* system error string or NULL */
+} bend_present_rr;
+ </synopsis>
+
+ <para>
+ The <function>bend_present</function> handler is called when
+ the server receives a Z39.50 Present Request.
+ The <literal>setname</literal>,
+ <literal>start</literal> and <literal>number</literal> is the
+ name of the result set - start position - and number of records to
+ be retrieved respectively. <literal>format</literal> and
+ <literal>comp</literal> is the preferred transfer syntax and element
+ specifications of the present request.
+ </para>
+ <para>
+ Note that this is handler serves as a supplement for
+ <function>bend_fetch</function> and need not to be defined in order to
+ support search - and retrieve.
+ </para>
+
+ </sect2>
+
+ <sect2><title>Delete</title>
+
+ <para>
+ For back-ends that supports delete of a result set only one handler
+ must be defined.
+ </para>
+
+ <synopsis>
+int (*bend_delete)(void *handle, bend_delete_rr *rr);
+
+typedef struct bend_delete_rr {
+ int function;
+ int num_setnames;
+ char **setnames;
+ Z_ReferenceId *referenceId;
+ int delete_status; /* status for the whole operation */
+ int *statuses; /* status each set - indexed as setnames */
+ ODR stream;
+ ODR print;
+} bend_delete_rr;
+ </synopsis>
+
+ <note>
+ <para>
+ The delete set function definition is rather primitive, mostly because
+ we have had no practical need for it as of yet. If someone wants
+ to provide a full delete service, we'd be happy to add the
+ extra parameters that are required. Are there clients out there
+ that will actually delete sets they no longer need?
+ </para>
+ </note>
+
+ </sect2>
+
+ <sect2><title>scan</title>
+
+ <para>
+ For servers that wish to offer the scan service one handler
+ must be defined.
+ </para>
+
+ <synopsis>
+int (*bend_delete)(void *handle, bend_delete_rr *rr);
+
+typedef enum {
+ BEND_SCAN_SUCCESS, /* ok */
+ BEND_SCAN_PARTIAL /* not all entries could be found */
+} bend_scan_status;
+
+typedef struct bend_scan_rr {
+ int num_bases; /* number of elements in database list */