Rename frontend.xml to server.xml
[yaz-moved-to-github.git] / doc / frontend.xml
diff --git a/doc/frontend.xml b/doc/frontend.xml
deleted file mode 100644 (file)
index 18a4f27..0000000
+++ /dev/null
@@ -1,893 +0,0 @@
- <chapter id="server"><title>Generic server</title>
-  <sect1 id="server.introduction"><title>Introduction</title>
-   
-   <para>
-    If you aren't into documentation, a good way to learn how the
-    back end interface works is to look at the <filename>backend.h</filename>
-    file. Then, look at the small dummy-server in
-    <filename>ztest/ztest.c</filename>. The <filename>backend.h</filename>
-    file also makes a good reference, once you've chewed your way through
-    the prose of this file.
-   </para>
-
-   <para>
-    If you have a database system that you would like to make available by
-    means of Z39.50 or SRU, &yaz; basically offers your two options. You
-    can use the APIs provided by the &asn;, &odr;, and &comstack;
-    modules to
-    create and decode PDUs, and exchange them with a client.
-    Using this low-level interface gives you access to all fields and
-    options of the protocol, and you can construct your server as close
-    to your existing database as you like.
-    It is also a fairly involved process, requiring
-    you to set up an event-handling mechanism, protocol state machine,
-    etc. To simplify server implementation, we have implemented a compact
-    and simple, but reasonably full-functioned server-frontend that will
-    handle most of the protocol mechanics, while leaving you to
-    concentrate on your database interface.
-   </para>
-
-   <note>
-    <para>
-     The backend interface was designed in anticipation of a specific
-     integration task, while still attempting to achieve some degree of
-     generality. We realize fully that there are points where the
-     interface can be improved significantly. If you have specific
-     functions or parameters that you think could be useful, send us a
-     mail (or better, sign on to the mailing list referred to in the
-     top-level README file). We will try to fit good suggestions into future
-     releases, to the extent that it can be done without requiring
-     too many structural changes in existing applications.
-    </para>
-   </note>
-
-   <note>
-    <para>
-     The &yaz; server does not support XCQL.
-     </para>
-   </note>
-  </sect1>
-  
-  <sect1 id="server.frontend"><title>The Database Frontend</title>
-
-   <para>
-    We refer to this software as a generic database frontend. Your
-    database system is the <emphasis>backend database</emphasis>, and the
-    interface between the two is called the <emphasis>backend API</emphasis>.
-    The backend API consists of a small number of function handlers and
-    structure definitions. You are required to provide the
-    <function>main()</function> routine for the server (which can be
-    quite simple), as well as a set of handlers to match each of the
-    prototypes.
-    The interface functions that you write can use any mechanism you like
-    to communicate with your database system: You might link the whole
-    thing together with your database application and access it by
-    function calls; you might use IPC to talk to a database server
-    somewhere; or you might link with third-party software that handles
-    the communication for you (like a commercial database client library).
-    At any rate, the handlers will perform the tasks of:
-   </para>
-
-   <itemizedlist>
-
-    <listitem><para>
-      Initialization.
-     </para></listitem>
-
-    <listitem><para>
-      Searching.
-     </para></listitem>
-
-    <listitem><para>
-      Fetching records.
-     </para></listitem>
-
-    <listitem><para>
-      Scanning the database index (optional - if you wish to implement SCAN).
-     </para></listitem>
-
-    <listitem><para>
-      Extended Services (optional).
-     </para></listitem>
-    
-    <listitem><para>
-      Result-Set Delete (optional).
-     </para></listitem>
-
-    <listitem><para>
-      Result-Set Sort (optional).
-     </para></listitem>
-    
-    <listitem><para>
-      Return Explain for SRU (optional).
-     </para></listitem>
-    
-   </itemizedlist>
-
-   <para>
-    (more functions will be added in time to support as much of
-    Z39.50-1995 as possible).
-   </para>
-
-  </sect1>
-  <sect1 id="server.backend"><title>The Backend API</title>
-
-   <para>
-    The header file that you need to use the interface are in the
-    <filename>include/yaz</filename> directory. It's called
-    <filename>backend.h</filename>. It will include other files from
-    the <filename>include/yaz</filename> directory, so you'll
-    probably want to use the -I option of your compiler to tell it
-    where to find the files. When you run
-    <literal>make</literal> in the top-level &yaz; directory,
-    everything you need to create your server is to link with the
-    <filename>lib/libyaz.la</filename> library.
-   </para>
-  </sect1>
-
-  <sect1 id="server.main"><title>Your main() Routine</title>
-
-   <para>
-    As mentioned, your <function>main()</function> routine can be quite brief.
-    If you want to initialize global parameters, or read global configuration
-    tables, this is the place to do it. At the end of the routine, you should
-    call the function
-   </para>
-
-   <synopsis>
-int statserv_main(int argc, char **argv,
-                  bend_initresult *(*bend_init)(bend_initrequest *r),
-                  void (*bend_close)(void *handle));
-   </synopsis>
-
-   <para>
-    The third and fourth arguments are pointers to handlers. Handler
-    <function>bend_init</function> is called whenever the server receives
-    an Initialize Request, so it serves as a Z39.50 session initializer. The
-    <function>bend_close</function> handler is called when the session is
-    closed.
-   </para>
-
-   <para>
-    <function>statserv_main</function> will establish listening sockets
-    according to the parameters given. When connection requests are received,
-    the event handler will typically <function>fork()</function> and
-    create a sub-process to handle a new connection.
-    Alternatively the server may be setup to create threads for each
-    connection.
-    If you do use global variables and forking, you should be aware, then,
-    that these cannot be shared between associations, unless you explicitly
-    disable forking by command line parameters. 
-   </para>
-   
-   <para>
-    The server provides a mechanism for controlling some of its behavior
-    without using command-line options. The function
-   </para>
-
-   <synopsis>
-    statserv_options_block *statserv_getcontrol(void);
-   </synopsis>
-
-   <para>
-    will return a pointer to a <literal>struct statserv_options_block</literal>
-    describing the current default settings of the server. The structure
-    contains these elements:
-    
-    <variablelist>
-     <varlistentry><term>
-       <literal>int dynamic</literal></term><listitem><para>
-       A boolean value, which determines whether the server
-       will fork on each incoming request (TRUE), or not (FALSE). Default is
-       TRUE. This flag is only read by UNIX-based servers (WIN32 based servers
-       doesn't fork).
-       </para></listitem></varlistentry>
-     
-     <varlistentry><term>
-       <literal>int threads</literal></term><listitem><para>
-       A boolean value, which determines whether the server
-       will create a thread on each incoming request (TRUE), or not (FALSE).
-       Default is FALSE. This flag is only read by UNIX-based servers
-       that offer POSIX Threads support.
-       WIN32-based servers always operate in threaded mode.
-       </para></listitem></varlistentry>
-     
-     <varlistentry><term>
-       <literal>int inetd</literal></term><listitem><para>
-       A boolean value, which determines whether the server
-       will operates under a UNIX INET daemon (inetd). Default is FALSE.
-       </para></listitem></varlistentry>
-     
-     <varlistentry><term>
-       <literal>char logfile[ODR_MAXNAME+1]</literal></term>
-      <listitem><para>File for diagnostic output (&quot;&quot;: stderr).
-       </para></listitem></varlistentry>
-     
-     <varlistentry><term>
-       <literal>char apdufile[ODR_MAXNAME+1]</literal></term>
-      <listitem><para>
-       Name of file for logging incoming and outgoing APDUs
-       (&quot;&quot;: don't log APDUs, &quot;-&quot;:
-       <literal>stderr</literal>).
-       </para></listitem></varlistentry>
-
-     <varlistentry><term>
-      <literal>char default_listen[1024]</literal></term>
-      <listitem><para>Same form as the command-line specification of
-       listener address. &quot;&quot;: no default listener address.
-       Default is to listen at &quot;tcp:@:9999&quot;. You can only
-       specify one default listener address in this fashion.
-       </para></listitem></varlistentry>
-
-     <varlistentry><term>
-      <literal>enum oid_proto default_proto;</literal></term>
-      <listitem><para>Either <literal>PROTO_Z3950</literal> or
-       <literal>PROTO_SR</literal>.
-       Default is <literal>PROTO_Z39_50</literal>.
-       </para></listitem></varlistentry>
-     
-     <varlistentry><term>
-       <literal>int idle_timeout;</literal></term>
-      <listitem><para>Maximum session idle-time, in minutes. Zero indicates
-       no (infinite) timeout. Default is 15 minutes.
-       </para></listitem></varlistentry>
-     
-     <varlistentry><term>
-       <literal>int maxrecordsize;</literal></term>
-      <listitem><para>Maximum permissible record (message) size. Default
-       is 1Mb. This amount of memory will only be allocated if a
-       client requests a very large amount of records in one operation
-       (or a big record).
-       Set it to a lower number if you are worried about resource
-       consumption on your host system.
-       </para></listitem></varlistentry>
-
-     <varlistentry><term>
-       <literal>char configname[ODR_MAXNAME+1]</literal></term>
-      <listitem><para>Passed to the backend when a new connection is received.
-       </para></listitem></varlistentry>
-
-     <varlistentry><term>
-       <literal>char setuid[ODR_MAXNAME+1]</literal></term>
-      <listitem><para>Set user id to the user specified, after binding
-       the listener addresses.
-       </para></listitem></varlistentry>
-     
-     <varlistentry><term>
-       <literal>void (*bend_start)(struct statserv_options_block *p)</literal>
-      </term>
-      <listitem><para>Pointer to function which is called after the
-       command line options have been parsed - but before the server
-       starts listening.
-       For forked UNIX servers this handler is called in the mother
-       process; for threaded servers this handler is called in the
-       main thread.
-       The default value of this pointer is NULL in which case it
-       isn't invoked by the frontend server.
-       When the server operates as an NT service this handler is called
-       whenever the service is started. 
-       </para></listitem></varlistentry>
-     
-     <varlistentry><term>
-       <literal>void (*bend_stop)(struct statserv_options_block *p)</literal>
-      </term>
-      <listitem><para>Pointer to function which is called whenever the server
-       has stopped listening for incoming connections. This function pointer
-       has a default value of NULL in which case it isn't called.
-       When the server operates as an NT service this handler is called
-       whenever the service is stopped.
-       </para></listitem></varlistentry>
-
-     <varlistentry><term>
-       <literal>void *handle</literal></term>
-      <listitem><para>User defined pointer (default value NULL).
-       This is a per-server handle that can be used to specify "user-data".
-       Do not confuse this with the session-handle as returned by bend_init.
-       </para></listitem></varlistentry>
-
-    </variablelist>
-   </para>
-
-   <para>
-    The pointer returned by <literal>statserv_getcontrol</literal> points to
-    a static area. You are allowed to change the contents of the structure,
-    but the changes will not take effect before you call
-   </para>
-   
-   <synopsis>
-void statserv_setcontrol(statserv_options_block *block);
-   </synopsis>
-
-   <note>
-    <para>
-     that you should generally update this structure before calling
-     <function>statserv_main()</function>.
-    </para>
-   </note>
-  </sect1>
-
-  <sect1 id="server.backendfunctions"><title>The Backend Functions</title>
-
-   <para>
-    For each service of the protocol, the backend interface declares one or
-    two functions. You are required to provide implementations of the
-    functions representing the services that you wish to implement.
-   </para>
-
-   <sect2 id="server.init"><title>Init</title>
-
-    <synopsis>
-bend_initresult (*bend_init)(bend_initrequest *r);
-    </synopsis>
-
-    <para>
-     This handler is called once for each new connection request, after
-     a new process/thread has been created, and an Initialize Request has
-     been received from the client. The pointer to the
-     <function>bend_init</function> handler is passed in the call to
-     <function>statserv_start</function>.
-    </para>
-
-    <para>
-     This handler is also called when operating in SRU mode - when
-     a connection has been made (even though SRU does not offer
-     this service).
-    </para>
-
-    <para>
-     Unlike previous versions of YAZ, the <function>bend_init</function> also
-     serves as a handler that defines the Z39.50 services that the backend
-     wish to support. Pointers to <emphasis>all</emphasis> service handlers,
-     including search - and fetch must be specified here in this handler.
-    </para>
-    <para>
-     The request  - and result structures are defined as
-    </para>
-
-    <synopsis>
-typedef struct bend_initrequest
-{
-    /** \brief user/name/password to be read */
-    Z_IdAuthentication *auth; 
-    /** \brief encoding stream (for results) */
-    ODR stream;
-    /** \brief printing stream */
-    ODR print;
-    /** \brief decoding stream (use stream for results) */
-    ODR decode; 
-    /** \brief reference ID */
-    Z_ReferenceId *referenceId;
-    /** \brief peer address of client */
-    char *peer_name;           
-    
-    /** \brief character set and language negotiation 
-
-    see include/yaz/z-charneg.h 
-    */
-    Z_CharSetandLanguageNegotiation *charneg_request;
-
-    /** \brief character negotiation response */
-    Z_External *charneg_response;
-
-    /** \brief character set (encoding) for query terms 
-        
-    This is NULL by default. It should be set to the native character
-    set that the backend assumes for query terms */
-    char *query_charset;      
-
-    /** \brief whehter query_charset also applies to recors 
-    
-    Is 0 (No) by default. Set to 1 (yes) if records is in the same
-    character set as queries. If in doubt, use 0 (No).
-    */
-    int records_in_same_charset;
-
-    char *implementation_id;
-    char *implementation_name;
-    char *implementation_version;
-
-    /** \brief Z39.50 sort handler */
-    int (*bend_sort)(void *handle, bend_sort_rr *rr);
-    /** \brief SRU/Z39.50 search handler */
-    int (*bend_search)(void *handle, bend_search_rr *rr);
-    /** \brief SRU/Z39.50 fetch handler */
-    int (*bend_fetch)(void *handle, bend_fetch_rr *rr);
-    /** \brief SRU/Z39.50 present handler */
-    int (*bend_present)(void *handle, bend_present_rr *rr);
-    /** \brief Z39.50 extended services handler */
-    int (*bend_esrequest) (void *handle, bend_esrequest_rr *rr);
-    /** \brief Z39.50 delete result set handler */
-    int (*bend_delete)(void *handle, bend_delete_rr *rr);
-    /** \brief Z39.50 scan handler */
-    int (*bend_scan)(void *handle, bend_scan_rr *rr);
-    /** \brief Z39.50 segment facility handler */
-    int (*bend_segment)(void *handle, bend_segment_rr *rr);
-    /** \brief SRU explain handler */
-    int (*bend_explain)(void *handle, bend_explain_rr *rr);
-    /** \brief SRU scan handler */
-    int (*bend_srw_scan)(void *handle, bend_scan_rr *rr);
-    /** \brief SRU record update handler */
-    int (*bend_srw_update)(void *handle, bend_update_rr *rr);
-
-    /** \brief whether named result sets are supported (0=disable, 1=enable) */
-    int named_result_sets;
-} bend_initrequest;
-
-typedef struct bend_initresult
-{
-    int errcode;               /* 0==OK */
-    char *errstring;           /* system error string or NULL */
-    void *handle;              /* private handle to the backend module */
-} bend_initresult;
-    </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 id="server.search.retrieve"><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; /* additional search info */
-    char *srw_sortKeys;        /* holds SRU/SRW sortKeys info */
-    char *srw_setname;         /* holds SRU/SRW generated resultsetID */
-    int *srw_setnameIdleTime;  /* holds SRU/SRW life-time */
-    int estimated_hit_count;   /* if hit count is estimated */
-    int partial_resultset;     /* if result set is partial */
-} 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 <link linkend="tools.oid">
-     OID tools</link>.
-    </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 SRU SearchRetrieveRequest.
-     For 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="cql.to.pqf">here</link>.
-    </para>
-
-    <para>
-     To maintain backwards compatibility, the frontend server
-     of yaz always assume that error codes are BIB-1 diagnostics.
-     For SRU operation, a Bib-1 diagnostic code is mapped to
-     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 */
-    Odr_oid *request_format;        /* format, transfer syntax (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?  */
-    Odr_oid *output_format;        /* response format/syntax (OID) */
-    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 SRU 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="tools.oid"/>).
-     A value of NULL for <literal>format</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 SRU SearchRetrieveRequest is received by the frontend server,
-     the <literal>referenceId</literal> is NULL and the
-     <literal>format</literal> (transfer syntax) is the OID for XML.
-     The schema for 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 */
-    Odr_oid *format;           /* format, transfer syntax (OID) */
-    Z_ReferenceId *referenceId;/* reference ID */
-    Z_RecordComposition *comp; /* Formatting instructions */
-    ODR stream;                /* encoding stream - memory source if required */
-    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 id="server.delete"><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 id="server.scan"><title>Scan</title>
-
-    <para>
-     For servers that wish to offer the scan service one handler
-     must be defined.
-    </para>
-
-    <synopsis>
-int (*bend_scan)(void *handle, bend_scan_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 databaselist */
-    char **basenames;   /* databases to search */
-    Odr_oid *attributeset;
-    Z_ReferenceId *referenceId; /* reference ID */
-    Z_AttributesPlusTerm *term;
-    ODR stream;         /* encoding stream - memory source if required */
-    ODR print;          /* printing stream */
-
-    int *step_size;     /* step size */
-    int term_position;  /* desired index of term in result list/returned */
-    int num_entries;    /* number of entries requested/returned */
-
-    /* scan term entries. The called handler does not have
-       to allocate this. Size of entries is num_entries (see above) */
-    struct scan_entry *entries;
-    bend_scan_status status;
-    int errcode;
-    char *errstring;
-    char *scanClause;   /* CQL scan clause */
-    char *setname;      /* Scan in result set (NULL if omitted) */
-} bend_scan_rr;
-    </synopsis>
-   <para>
-    This backend server handles both Z39.50 scan 
-    and SRU scan. In order for a handler to distinguish between SRU (CQL) scan 
-    Z39.50 Scan , it must check for a non-NULL value of 
-    <literal>scanClause</literal>.
-   </para>
-   <note>
-    <para>
-     if designed today, it would be a choice using a union or similar,
-     but that would break binary compatibility with existing servers.
-    </para>
-    </note>
-   </sect2>
-  </sect1>
-
-  <sect1 id="server.invocation"><title>Application Invocation</title>
-
-   <para>
-    The finished application has the following
-    invocation syntax (by way of <function>statserv_main()</function>):
-   </para>
-
-   &gfs-synopsis;
-   
-   <para>
-    The options are:
-
-    &gfs-options;
-
-   </para>
-   
-   <para>
-    A listener specification consists of a transport mode followed by a
-    colon (:) followed by a listener address. The transport mode is
-    either <literal>tcp</literal>, <literal>unix:</literal> or
-    <literal>ssl</literal>.
-   </para>
-   
-   <para>
-    For TCP and SSL, an address has the form
-   </para>
-
-   <synopsis>
-    hostname | IP-number [: portnumber]
-   </synopsis>
-   
-   <para>
-    The port number defaults to 210 (standard Z39.50 port).
-   </para>
-
-   <para>
-    For UNIX, the address is the filename of socket.
-   </para>
-
-   <para>
-    For TCP/IP and SSL, the special hostname <literal>@</literal> 
-    (at sign) is mapped to the address <literal>INADDR_ANY</literal>,
-    which causes the server to listen on any local interface. 
-   </para>
-
-   <example id="server.example.running.unix"><title>Running the GFS on Unix</title>
-    <para>
-     Assuming the server application <replaceable>appname</replaceable> is
-     started as root, the following will make it listen on port 210.
-     The server will change identity to <literal>nobody</literal>
-     and write its log to <filename>/var/log/app.log</filename>.
-     <screen>
-      application -l /var/log/app.log -u nobody tcp:@:210
-     </screen>
-    </para>
-    <para>
-     The server will accept Z39.50 requests and offer SRU service on port 210.
-    </para>
-   </example>
-   <example id="server.example.apache.sru"><title>Setting up Apache as SRU Frontend</title>
-    <para>
-     If you use <ulink url="&url.apache;">Apache</ulink>
-     as your public web server and want to offer HTTP port 80
-     access to the YAZ server on 210, you can use the
-     <ulink url="&url.apache.directive.proxypass;">
-      <literal>ProxyPass</literal></ulink> 
-     directive.
-     If you have virtual host
-     <literal>srw.mydomain</literal> you can use the following directives
-     in Apache's httpd.conf:
-     <screen>
-      &lt;VirtualHost *>
-       ErrorLog /home/srw/logs/error_log
-       TransferLog /home/srw/logs/access_log
-       ProxyPass / http://srw.mydomain:210/
-      &lt;/VirtualHost>
-     </screen>
-    </para>
-    <para>
-     The above for the Apache 1.3 series.
-    </para>
-   </example>
-   <example id="server.example.local.access">
-    <title>Running a server with local access only</title>
-    <para>
-     Servers that is only being accessed from the local host should listen
-     on UNIX file socket rather than a Internet socket. To listen on
-     <filename>/tmp/mysocket</filename> start the server as follows:
-     <screen>
-      application unix:/tmp/mysocket
-     </screen>
-    </para>
-   </example>
-  </sect1>
-  <sect1 id="server.vhosts"><title>GFS Configuration and Virtual Hosts</title>
-   &gfs-virtual;
-  </sect1>
- </chapter>
- <!-- Keep this comment at the end of the file
- Local variables:
- mode: sgml
- sgml-omittag:t
- sgml-shorttag:t
- sgml-minimize-attributes:nil
- sgml-always-quote-attributes:t
- sgml-indent-step:1
- sgml-indent-data:t
- sgml-parent-document: "yaz.xml"
- sgml-local-catalogs: nil
- sgml-namecase-general:t
- End:
- -->