man pages
authorAdam Dickmeiss <adam@indexdata.dk>
Mon, 16 Sep 2002 14:16:31 +0000 (14:16 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Mon, 16 Sep 2002 14:16:31 +0000 (14:16 +0000)
13 files changed:
configure.in
debian/rules
doc/Makefile.am
doc/client.xml
doc/frontend.xml
doc/yaz-client-commands.xml [new file with mode: 0644]
doc/yaz-client.sgml [new file with mode: 0644]
doc/yaz-config.sgml [new file with mode: 0644]
doc/yaz-man.sgml [new file with mode: 0644]
doc/yaz-ztest.sgml [new file with mode: 0644]
doc/yaz.sgml [deleted file]
doc/yaz.xml.in
doc/ztest-options.xml [new file with mode: 0644]

index 1046871..cf5c14d 100644 (file)
@@ -1,6 +1,6 @@
 dnl YAZ Toolkit, Index Data 1994-2002
 dnl See the file LICENSE for details.
-dnl $Id: configure.in,v 1.87 2002-09-11 21:25:56 adam Exp $
+dnl $Id: configure.in,v 1.88 2002-09-16 14:16:31 adam Exp $
 AC_INIT(include/yaz/yaz-version.h)
 AM_INIT_AUTOMAKE(yaz, 1.9.1)
 dnl
@@ -183,7 +183,7 @@ else
 #include <unistd.h>
 #include <sys/socket.h>
 ],
-       [getpeername(0, (struct sockaddr *)NULL, (size_t *)0);],
+       [size_t mylen; getpeername(0, (struct sockaddr *)NULL, &mylen);],
        ac_cv_check_getpeername_accepts_size_t=yes,
        ac_cv_check_getpeername_accepts_size_t=no)])
        AC_MSG_RESULT($ac_cv_check_getpeername_accepts_size_t)
index 9ba9281..b8c2d8c 100755 (executable)
@@ -118,7 +118,8 @@ endif
 
        dh_installdeb -p yaz-runtime
        dh_installdeb -p yaz-devel
-       dh_undocumented -p yaz-runtime yaz-client.1 yaz-comp.1 yaz-config.1 yaz-ztest.1 zoomsh.1
+       dh_installman -p yaz-runtime doc/yaz-client.1 doc/yaz-ztest.8 doc/yaz-config.1 doc/yaz.7
+       dh_undocumented -p yaz-runtime yaz-comp.1 zoomsh.1
        echo "libyaz 1 yaz-runtime" > debian/yaz-runtime/DEBIAN/shlibs
        echo "libyazthread 1 yaz-runtime" >> debian/yaz-runtime/DEBIAN/shlibs
        echo "libyazmalloc 1 yaz-runtime" >> debian/yaz-runtime/DEBIAN/shlibs
@@ -126,7 +127,7 @@ endif
        dh_shlibdeps -p yaz-runtime $(LOCAL_LINK) 
 ifeq ($(YAZ_WITH_SSL),1)
        dh_installdeb -p yaz-ssl
-       dh_undocumented -p yaz-ssl yaz-client-ssl.1 yaz-ztest-ssl.1
+       dh_installman -p yaz-ssl doc/yaz-client-ssl.1 doc/yaz-ztest-ssl.8
        echo "libyazssl 1 yaz-ssl" >> debian/yaz-ssl/DEBIAN/shlibs
        chmod 644 debian/yaz-ssl/DEBIAN/shlibs
        dh_shlibdeps -p yaz-ssl $(LOCAL_LINK)
index 0488d13..f1a3a19 100644 (file)
@@ -1,4 +1,4 @@
-## $Id: Makefile.am,v 1.31 2002-06-02 18:50:40 adam Exp $
+## $Id: Makefile.am,v 1.32 2002-09-16 14:16:31 adam Exp $
 
 docdir=$(datadir)/doc/@PACKAGE@
 
@@ -6,7 +6,8 @@ XMLFILES=$(srcdir)/yaz.xml.in $(srcdir)/introduction.xml \
  $(srcdir)/installation.xml $(srcdir)/indexdata.xml $(srcdir)/asn.xml \
  $(srcdir)/tools.xml $(srcdir)/odr.xml $(srcdir)/comstack.xml \
  $(srcdir)/frontend.xml $(srcdir)/license.xml $(srcdir)/future.xml  \
- $(srcdir)/client.xml $(srcdir)/zoom.xml $(srcdir)/credits.xml
+ $(srcdir)/client.xml $(srcdir)/zoom.xml $(srcdir)/credits.xml \
+ $(srcdir)/ztest-options.xml $(srcdir)/yaz-client-commands.xml
 
 HTMLFILES = asn.external.html asn.html asn.oid.html asn.pdu.html \
  asn.preparing.html client.commands.html client.html client.invoking.html \
@@ -25,12 +26,34 @@ HTMLFILES = asn.external.html asn.html asn.oid.html asn.pdu.html \
  zoom.scan.html
 
 DOCFILES=$(HTMLFILES) yaz.pdf
+MANFILES=yaz-client.1 yaz-client-ssl.1 yaz-ztest.8 \
+       yaz-ztest-ssl.8 yaz-config.1 yaz.7
+REFFILES=yaz-client.sgml yaz-ztest.sgml yaz-config.sgml yaz-man.sgml
 
 SUPPORTFILES=yazhtml.dsl yazphp.dsl yazprint.dsl xml.dcl id.eps id.png
 
-EXTRA_DIST = $(XMLFILES) $(SUPPORTFILES) $(DOCFILES)
+EXTRA_DIST = $(XMLFILES) $(SUPPORTFILES) $(DOCFILES) $(MANFILES) $(REFFILES)
 
 doc_DATA = $(DOCFILES)
+man_MANS = $(MANFILES)
+
+yaz-client.1: yaz-client.sgml
+       cd $(srcdir); docbook2man yaz-client.sgml
+
+yaz-ztest.8: yaz-ztest.sgml
+       cd $(srcdir); docbook2man yaz-ztest.sgml
+
+yaz-config.1: yaz-config.sgml
+       cd $(srcdir); docbook2man yaz-config.sgml
+
+yaz.7: yaz-man.sgml
+       cd $(srcdir); docbook2man yaz-man.sgml
+
+yaz-ztest-ssl.8: yaz-ztest.8
+       ln -s yaz-ztest.8 yaz-ztest-ssl.8
+
+yaz-client-ssl.1: yaz-client.1
+       ln -s yaz-client.1 yaz-client-ssl.1
 
 $(HTMLFILES): $(XMLFILES) 
        cd $(srcdir); jade -E14 -d yazhtml.dsl -t sgml xml.dcl yaz.xml
index 48c699d..0760a4b 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Id: client.xml,v 1.13 2002-08-17 07:55:51 adam Exp $ -->
+<!-- $Id: client.xml,v 1.14 2002-09-16 14:16:31 adam Exp $ -->
  <chapter id="client"><title>The YAZ client</title>
   <sect1 id="client.introduction"><title>Introduction</title>
    <para>
       <literal>-k</literal> <replaceable>size</replaceable>
      </term><listitem>
       <simpara>Specifies the maximum messages size in kilobytes.
-       The default maximum messages for the YAZ client is 1024
+       The default maximum message size for the YAZ client is 1024
        (1 MB).
       </simpara></listitem>
     </varlistentry>
     The commands are (the letters in parenthesis are short
     names for the commands):
    </para>
-   <variablelist>
-    <varlistentry><term>
-      <literal>open </literal><replaceable>zurl</replaceable>
-     </term>
-     <listitem>
-      <para>Opens a connection to a server. The syntax for
-       <replaceable>zurl</replaceable> is the same as described
-       above for connecting from the command line.
-      </para>
-      <para>
-       Syntax:
-      </para>
-      <para>
-       [<literal>(tcp|ssl|unix)':'</literal>]<replaceable>host</replaceable>
-       [:<replaceable>port</replaceable>][/<replaceable>base&gt;</replaceable>]
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>quit</literal>
-     </term>
-     <listitem>
-      <para>Ends YAZ client</para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>f </literal><replaceable>query</replaceable></term>
-     <listitem>
-      <para>Sends a Search Request using the <replaceable>query</replaceable>
-       given.
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>delete</literal> <replaceable>setname</replaceable></term>
-     <listitem>
-      <para>Deletes result set with name <replaceable>setname</replaceable>
-       on the server.</para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>base </literal><replaceable>base1</replaceable>
-      <replaceable>base2</replaceable> ...
-      </term>
-     <listitem>
-      <para>Sets the name(s) of the database(s) to search. One or more
-       databases may be specified separated by blanks. This commands overrides
-       the database given in <replaceable>zurl</replaceable>.
-       </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>show </literal>
-      [<replaceable>start</replaceable>[+<replaceable>number</replaceable>]]
-      </term>
-     <term><literal>s</literal></term>
-     <listitem>
-      <para>Fetches records by sending a Present Request from the start
-       position given by
-       <replaceable>start</replaceable>
-       a number of records given by <replaceable>number</replaceable>. If
-       <replaceable>start</replaceable> is not given, then the client
-       will fetch from position of the last retrieved record plus 1. If
-       <replaceable>number</replaceable> is not given, then one record will
-       be fetched at a time.
-      </para>
-      </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>scan</literal> <replaceable>term</replaceable>
-     </term>
-     <listitem>
-      <simpara>Scans
-       database index for a term. The syntax resembles the syntax
-       for <literal>find</literal>.
-       If you want to scan for the word <literal>water</literal> you could
-       write
-       </simpara>
-      <screen>
-       scan water
-      </screen>
-      <simpara>
-       but if you want to scan only in, say the title field, you would write
-       </simpara>
-      <screen>
-       scan @attr 1=4 water
-      </screen>
-     </listitem>
-    </varlistentry>
-    <varlistentry id="sortspec"><term>
-      <literal>sort</literal> <replaceable>sortspecs</replaceable>
-     </term>
-     <listitem>
-      <para>Sorts a result set. The sort command takes a
-       sequence of sort specifications. A sort
-       specification holds a field (sort criteria) and is followed by flags.
-       If the sort criteria includes <literal>=</literal> it is assumed
-       that the sort SortKey is of type sortAttributes using Bib-1.
-       The integer before <literal>=</literal> is
-       the attribute type and the integer following <literal>=</literal>
-       is the attribute value.
-       If no <literal>=</literal> is in the SortKey it is treated as a
-       sortfield-type of type InternationalString.
-       Flags observed are: <literal>s</literal>
-       for case sensitive, <literal>i</literal> for case insensitive,
-       <literal>&lt;</literal> for sort ascending and <literal>&gt;</literal>
-       for sort descending.
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>sort+</literal>
-     </term>
-     <listitem>
-      <para>Same as <literal>sort</literal> but stores the sorted
-       result set in a new result set.
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>authentication</literal> <replaceable>openauth</replaceable>
-      </term>
-     <listitem>
-      <para>Sets up a authentication string if a server requires
-       authentication (v2 OpenStyle). The authentication string is first
-       sent to the server when the <literal>open</literal> command is
-       issued and the Z39.50 Initialize Request is sent, so this command
-       must be used before <literal>open</literal> in order to be effective.
-       A common convention for the <replaceable>authopen</replaceable> string
-       is that the username - and password is separated by a slash, e.g.
-       <literal>myusername/mysecret</literal>.
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>lslb</literal> <replaceable>n</replaceable>
-     </term>
-     <listitem>
-      <para>Sets the limit for when no records should be returned
-       together with the search result.
-       See the
-       <ulink
-       url="http://lcweb.loc.gov/z3950/agency/markup/04.html#3.2.2.1.6">
-       Z39.50 standard
-       </ulink>
-       for more details.
-      </para>
-     </listitem>
-    </varlistentry>
-
-    <varlistentry><term>
-      <literal>ssub</literal> <replaceable>n</replaceable>
-     </term>
-     <listitem>
-      <para>Sets the limit for when all records should be returned with
-       the search result.
-       See the
-       <ulink
-       url="http://lcweb.loc.gov/z3950/agency/markup/04.html#3.2.2.1.6">
-       Z39.50 standard
-       </ulink> for more details.
-      </para>
-     </listitem>
-    </varlistentry>
-    
-    <varlistentry><term>
-      <literal>mspn</literal> <replaceable>n</replaceable>
-     </term>
-     <listitem>
-      <para>Sets the number of records should be returned if the
-       number of records in the result set is between the values of
-       <literal>lslb</literal> and <literal>ssub</literal>.
-       See the
-       <ulink
-       url="http://lcweb.loc.gov/z3950/agency/markup/04.html#3.2.2.1.6">
-       Z39.50 standard
-       </ulink>
-       for more details.
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>status</literal>
-     </term>
-     <listitem>
-      <para>Displays the values of <literal>lslb</literal>,
-       <literal>ssub</literal> and <literal>mspn</literal>.
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>setname</literal>
-     </term>
-     <listitem>
-      <para>Switches named result sets on and off. Default is on.
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>cancel</literal>
-     </term>
-     <listitem>
-      <para>Sends a Trigger Resource Control Request to the target.
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>format</literal> <replaceable>oid</replaceable>
-     </term>
-     <listitem>
-      <para>Sets the preferred transfer syntax for retrieved records.
-       yaz-client supports all the record syntaxes that currently
-       are registered. See
-       <ulink
-       url="http://lcweb.loc.gov/z3950/agency/defns/oids.html#5">
-       Z39.50 Standard
-       </ulink>
-       for more details. Commonly used records syntaxes include usmarc,
-       sutrs, grs1 and xml.
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>elements</literal> <replaceable>e</replaceable>
-     </term>
-     <listitem>
-      <para>Sets the element set name for the records. Many targets support
-       element sets are B (for brief) and F (for full).
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>close</literal>
-     </term>
-     <listitem>
-      <para>Sends a Z39.50 Close APDU and closes connection with the peer
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>querytype</literal> <replaceable>type</replaceable>
-     </term>
-     <listitem>
-      <para>Sets the query type as used by command <literal>find</literal>.
-       The following is supported: <literal>prefix</literal> for 
-       <link linkend="PQF">Prefix Query Notation</link> (Type-1 Query);
-       <literal>ccl</literal> for CCL search (Type-2
-       Query) or <literal>ccl2rpn</literal> for
-       <link linkend="CCL">CCL</link> to RPN conversion (Type-1 Query).
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>attributeset</literal> <replaceable>set</replaceable>
-     </term>
-     <listitem>
-      <para>
-       Sets attribute set OID for prefix queries (RPN, Type-1).
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>refid</literal> <replaceable>id</replaceable>
-      </term>
-     <listitem>
-      <para>Sets reference ID for Z39.50 Request(s).
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-     <literal>itemorder</literal>
-      <replaceable>type</replaceable> <replaceable>no</replaceable>
-     </term>
-     <listitem>
-      <para>Sends an Item Order Request using the ILL External. 
-       <replaceable>type</replaceable> is either 1 or 2 which corresponds to
-       ILL-Profile 1 and 2 respectively. The <replaceable>no</replaceable>
-       is the Result Set position of the record to be ordered.
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry><term>
-      <literal>update</literal>
-     </term>
-     <listitem>
-      <para>Sends Item Update Request. This command sends a "minimal"
-       PDU Update to the target supplying the last received record from
-       the target.
-       If no record has been received from the target this command is ignored
-       and nothing is sent to the target.
-      </para>
-     </listitem>
-    </varlistentry>
 
-    <varlistentry><term>
-      <literal>.</literal>
-      <replaceable>filename</replaceable>
-     </term>
-     <listitem>
-      <para>Executes list of commands from
-       file <replaceable>filename</replaceable>, just like source on
-       most UNIX shells.
-      </para>
-     </listitem>
-    </varlistentry>
+   &yaz-client-commands;
 
-    <varlistentry><term>
-      <literal>!</literal>
-      <replaceable>args</replaceable>
-     </term>
-     <listitem>
-      <para>Executes command <replaceable>args</replaceable> in subshell
-       using the <literal>system</literal> call.
-      </para>
-     </listitem>
-    </varlistentry>
-
-    <varlistentry><term>
-      <literal>push_commande</literal>
-      <replaceable>command</replaceable>
-     </term>
-     <listitem>
-      <para>The push_command takes another command as its argument.
-       That command is then added to the history information (so
-       you can retrieve it later). The command itself is not
-       executed. This command only works if you have GNU readline/history
-       enabled.
-      </para>
-     </listitem>
-    </varlistentry>
-
-    <varlistentry><term>
-      <literal>set_apdufile</literal>
-      <replaceable>filename</replaceable>
-     </term>
-     <listitem>
-      <para>Sets that APDU should be logged to file
-       <replaceable>filename</replaceable>. This command does the
-       thing as option <literal>-a</literal>.
-      </para>
-     </listitem>
-    </varlistentry>
-
-    <varlistentry><term>
-      <literal>set_marcdump</literal>
-      <replaceable>filename</replaceable>
-     </term>
-     <listitem>
-      <para>Specifies that all retrieved records should be appended ot
-       file <replaceable>filename</replaceable>. This command does the
-       thing as option <literal>-m</literal>.
-      </para>
-     </listitem>
-    </varlistentry>
-
-    <varlistentry><term>
-      <literal>set_cclfields</literal>
-      <replaceable>filename</replaceable>
-     </term>
-     <listitem>
-      <para>Specifies that CCL fields should be read from file
-       file <replaceable>filename</replaceable>. This command does the
-       thing as option <literal>-c</literal>.
-      </para>
-     </listitem>
-    </varlistentry>
-
-    <varlistentry><term>
-      <literal>register_oid</literal>
-      <replaceable>name</replaceable>
-      <replaceable>class</replaceable>
-      <replaceable>OID</replaceable>
-     </term>
-     <listitem>
-      <para>This command allows you to register your own object
-       identifier - so that instead of entering a long dot-notation
-       you can use a short name instead.
-       The <replaceable>name</replaceable> is your
-       name for the OID, <replaceable>class</replaceable> is the
-       class, and <replaceable>OID</replaceable> is the raw OID in
-       dot notation. Class is one <literal>appctx</literal>,
-       <literal>absyn</literal>, <literal>attet</literal>,
-       <literal>transyn</literal>, <literal>diagset</literal>,
-       <literal>recsyn</literal>, <literal>resform</literal>,
-       <literal>accform</literal>, <literal>extserv</literal>,
-       <literal>userinfo</literal>, <literal>elemspec</literal>,
-       <literal>varset</literal>, <literal>schema</literal>,
-       <literal>tagset</literal>, <literal>general</literal>.
-       If you're in doubt use the <literal>general</literal>
-        class.
-      </para>
-     </listitem>
-    </varlistentry>
-
-   </variablelist>
   </sect1>
   <sect1 id="client.searching"><title>Searching</title>
    <para>
index 297c5f3..65d21fc 100644 (file)
@@ -1,7 +1,7 @@
-<!-- $Id: frontend.xml,v 1.13 2002-08-17 07:55:51 adam Exp $ -->
+<!-- $Id: frontend.xml,v 1.14 2002-09-16 14:16:31 adam Exp $ -->
  <chapter id="server"><title>Generic server</title>
   <sect1><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>
@@ -52,7 +52,8 @@
     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.
+    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
@@ -397,7 +398,8 @@ typedef struct bend_initresult
      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
+     <literal>implementation_version</literal> holds
+     DNS of client, ID of implementor, name
      of client (Z39.50) implementation - and version.
     </para>
 
@@ -678,132 +680,28 @@ typedef struct bend_scan_rr {
     The finished application has the following
     invocation syntax (by way of <function>statserv_main()</function>):
    </para>
-
-   <synopsis>
-    <replaceable>appname</replaceable> &lsqb;-szSiT1 -u <replaceable>uid</replaceable> -a <replaceable>apdufile</replaceable> -l <replaceable>logfile</replaceable> -v <replaceable>loglevel</replaceable> -c <replaceable>config</replaceable>&rsqb;
-    &lsqb;listener ...&rsqb;
-   </synopsis>
-
+   
+   <cmdsynopsis>
+    <command>appname</command>
+    <arg choice="opt"><option>-a <replaceable>file</replaceable></option></arg>
+    <arg choice="opt"><option>-v <replaceable>level</replaceable></option></arg>
+    <arg choice="opt"><option>-l <replaceable>file</replaceable></option></arg>
+    <arg choice="opt"><option>-u <replaceable>uid</replaceable></option></arg>
+    <arg choice="opt"><option>-c <replaceable>config</replaceable></option></arg>
+    <arg choice="opt"><option>-t <replaceable>minutes</replaceable></option></arg>
+    <sbr/>
+    <arg choice="opt"><option>-k <replaceable>kilobytes</replaceable></option></arg>
+    <arg choice="opt"><option>-d <replaceable>daemon</replaceable></option></arg>
+    <arg choice="opt"><option>-ziST1</option></arg>
+    <arg choice="opt"><option>-w <replaceable>dir</replaceable></option></arg>
+    <arg choice="opt" rep="repeat">listener-spec</arg>
+   </cmdsynopsis>
+   
    <para>
-    The options are
+    The options are:
 
-    <variablelist>
-
-     <varlistentry><term><literal>-a </literal>
-       <replaceable>apdufile</replaceable></term>
-      <listitem><para>
-       Specify a file for dumping PDUs (for diagnostic purposes).
-       The special name &quot;-&quot; sends output to
-       <literal>stderr</literal>.
-       </para></listitem></varlistentry>
-
-     <varlistentry><term><literal>-S</literal></term>
-      <listitem><para>
-       Don't fork or make threads on connection requests. This is good for
-       debugging, but not recommended for real operation: Although the
-       server is asynchronous and non-blocking, it can be nice to keep
-       a software malfunction (okay then, a crash) from affecting all
-       current users.
-       </para></listitem></varlistentry>
-
-     <varlistentry><term><literal>-1</literal></term>
-      <listitem><para>
-        Like <literal>-S</literal> but after one session the server
-        exits. This mode is for debugging <emphasis>only</emphasis>.
-       </para></listitem></varlistentry>
-     
-     <varlistentry><term><literal>-T</literal></term>
-      <listitem><para>
-       Operate the server in threaded mode. The server creates a thread
-       for each connection rather than a fork a process. Only available
-       on UNIX systems that offers POSIX threads.
-       </para></listitem></varlistentry>
-
-     <varlistentry><term><literal>-s</literal></term>
-      <listitem><para>
-       Use the SR protocol (obsolete).
-       </para></listitem></varlistentry>
-
-     <varlistentry><term><literal>-z</literal></term>
-      <listitem><para>
-       Use the Z39.50 protocol (default). These two options complement
-       each other. You can use both multiple times on the same command
-       line, between listener-specifications (see below). This way, you
-       can set up the server to listen for connections in both protocols
-       concurrently, on different local ports.
-       </para></listitem></varlistentry>
-
-     <varlistentry><term><literal>-l </literal>
-       <replaceable>file</replaceable></term>
-      <listitem><para>The logfile.
-       </para></listitem></varlistentry>
+    &ztest-options;
 
-     <varlistentry><term><literal>-c </literal>
-       <replaceable>config</replaceable></term>
-      <listitem><para>A user option that serves as a specifier for some
-       sort of configuration, e.g. a filename.
-       The argument to this option is transferred to member
-       <literal>configname</literal>of the
-       <literal>statserv_options_block</literal>.
-       </para></listitem></varlistentry>
-
-     <varlistentry><term><literal>-v </literal>
-       <replaceable>level</replaceable></term>
-      <listitem><para>
-       The log level. Use a comma-separated list of members of the set
-       {fatal,debug,warn,log,malloc,all,none}.
-       </para></listitem></varlistentry>
-
-     <varlistentry><term><literal>-u </literal>
-       <replaceable>uid</replaceable></term>
-      <listitem><para>
-       Set user ID. Sets the real UID of the server process to that of the
-       given user. It's useful if you aren't comfortable with having the
-       server run as root, but you need to start it as such to bind a
-       privileged port.
-       </para></listitem></varlistentry>
-
-     <varlistentry><term><literal>-w </literal>
-       <replaceable>dir</replaceable></term>
-      <listitem><para>
-       The server changes to this directory during before listening 
-        on incoming connections. This option is useful
-        when the server is operating from the <application>inetd</application>
-         daemon (see <literal>-i</literal>).
-       </para></listitem></varlistentry>
-
-     <varlistentry><term><literal>-i</literal></term>
-      <listitem><para>
-       Use this to make the the server run from the
-        <application>inetd</application> server (UNIX only).
-       </para></listitem></varlistentry>
-     
-     <varlistentry><term><literal>-install</literal></term>
-      <listitem><para>
-       Use this to install the server as an NT service
-        (Windows 2000/NT only). 
-        Control the server by going to the Services in the Control Panel.
-       </para></listitem></varlistentry>
-     
-     <varlistentry><term><literal>-remove</literal></term>
-      <listitem><para>
-       Use this to remove the server from the NT services
-        (Windows 2000/NT only). 
-       </para></listitem></varlistentry>
-     
-     <varlistentry><term><literal>-t </literal>
-       <replaceable>minutes</replaceable></term>
-      <listitem><para>
-       Idle session timeout, in minutes.
-       </para></listitem></varlistentry>
-     
-     <varlistentry><term><literal>-k </literal>
-       <replaceable>size</replaceable></term>
-      <listitem><para>
-       Maximum record size/message size, in kilobytes.
-       </para></listitem></varlistentry>
-     
-    </variablelist>
    </para>
    
    <para>
@@ -826,7 +724,7 @@ typedef struct bend_scan_rr {
    </para>
 
    <para>
-    For UNIX local socket the address is the name local file.
+    For UNIX, the address is the filename of socket.
    </para>
    
    <para>
@@ -849,7 +747,7 @@ typedef struct bend_scan_rr {
 
   </sect1>
  </chapter>
-
  <!-- Keep this comment at the end of the file
  Local variables:
  mode: sgml
diff --git a/doc/yaz-client-commands.xml b/doc/yaz-client-commands.xml
new file mode 100644 (file)
index 0000000..e762e25
--- /dev/null
@@ -0,0 +1,413 @@
+<!-- 
+   $Id: yaz-client-commands.xml,v 1.1 2002-09-16 14:16:31 adam Exp $
+   Commands for YAZ client.
+   Included in both manual and man page for yaz-client.
+-->
+<variablelist>
+ <varlistentry><term>
+   <literal>open </literal><replaceable>zurl</replaceable>
+  </term>
+  <listitem>
+   <para>Opens a connection to a server. The syntax for
+    <replaceable>zurl</replaceable> is the same as described
+    above for connecting from the command line.
+   </para>
+   <para>
+    Syntax:
+   </para>
+   <para>
+    [<literal>(tcp|ssl|unix)':'</literal>]<replaceable>host</replaceable>
+    [:<replaceable>port</replaceable>][/<replaceable>base&gt;</replaceable>]
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>quit</literal>
+  </term>
+  <listitem>
+   <para>Ends YAZ client</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>f </literal><replaceable>query</replaceable></term>
+  <listitem>
+   <para>Sends a Search Request using the <replaceable>query</replaceable>
+    given.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>delete</literal> <replaceable>setname</replaceable></term>
+  <listitem>
+   <para>Deletes result set with name <replaceable>setname</replaceable>
+    on the server.</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>base </literal><replaceable>base1</replaceable>
+   <replaceable>base2</replaceable> ...
+  </term>
+  <listitem>
+   <para>Sets the name(s) of the database(s) to search. One or more
+    databases may be specified separated by blanks. This commands overrides
+    the database given in <replaceable>zurl</replaceable>.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>show </literal>
+   [<replaceable>start</replaceable>[+<replaceable>number</replaceable>]]
+  </term>
+  <listitem>
+   <para>Fetches records by sending a Present Request from the start
+    position given by
+    <replaceable>start</replaceable>
+    a number of records given by <replaceable>number</replaceable>. If
+    <replaceable>start</replaceable> is not given, then the client
+    will fetch from position of the last retrieved record plus 1. If
+    <replaceable>number</replaceable> is not given, then one record will
+    be fetched at a time.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>scan</literal> <replaceable>term</replaceable>
+  </term>
+  <listitem>
+   <simpara>Scans
+    database index for a term. The syntax resembles the syntax
+    for <literal>find</literal>.
+    If you want to scan for the word <literal>water</literal> you could
+    write
+   </simpara>
+   <screen>
+    scan water
+   </screen>
+   <simpara>
+    but if you want to scan only in, say the title field, you would write
+   </simpara>
+   <screen>
+    scan @attr 1=4 water
+   </screen>
+  </listitem>
+ </varlistentry>
+ <varlistentry id="sortspec"><term>
+   <literal>sort</literal> <replaceable>sortspecs</replaceable>
+  </term>
+  <listitem>
+   <para>Sorts a result set. The sort command takes a
+    sequence of sort specifications. A sort
+    specification holds a field (sort criteria) and is followed by flags.
+    If the sort criteria includes <literal>=</literal> it is assumed
+    that the sort SortKey is of type sortAttributes using Bib-1.
+    The integer before <literal>=</literal> is
+    the attribute type and the integer following <literal>=</literal>
+    is the attribute value.
+    If no <literal>=</literal> is in the SortKey it is treated as a
+    sortfield-type of type InternationalString.
+    Flags observed are: <literal>s</literal>
+    for case sensitive, <literal>i</literal> for case insensitive,
+    <literal>&lt;</literal> for sort ascending and <literal>&gt;</literal>
+    for sort descending.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>sort+</literal>
+  </term>
+  <listitem>
+   <para>Same as <literal>sort</literal> but stores the sorted
+    result set in a new result set.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>authentication</literal> <replaceable>openauth</replaceable>
+  </term>
+  <listitem>
+   <para>Sets up a authentication string if a server requires
+    authentication (v2 OpenStyle). The authentication string is first
+    sent to the server when the <literal>open</literal> command is
+    issued and the Z39.50 Initialize Request is sent, so this command
+    must be used before <literal>open</literal> in order to be effective.
+    A common convention for the <replaceable>authopen</replaceable> string
+    is that the username - and password is separated by a slash, e.g.
+    <literal>myusername/mysecret</literal>.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>lslb</literal> <replaceable>n</replaceable>
+  </term>
+  <listitem>
+   <para>Sets the limit for when no records should be returned
+    together with the search result.
+    See the
+    <ulink
+           url="http://lcweb.loc.gov/z3950/agency/markup/04.html#3.2.2.1.6">
+     Z39.50 standard
+    </ulink>
+    for more details.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry><term>
+   <literal>ssub</literal> <replaceable>n</replaceable>
+  </term>
+  <listitem>
+   <para>Sets the limit for when all records should be returned with
+    the search result.
+    See the
+    <ulink
+           url="http://lcweb.loc.gov/z3950/agency/markup/04.html#3.2.2.1.6">
+     Z39.50 standard
+    </ulink> for more details.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>mspn</literal> <replaceable>n</replaceable>
+  </term>
+  <listitem>
+   <para>Sets the number of records should be returned if the
+    number of records in the result set is between the values of
+    <literal>lslb</literal> and <literal>ssub</literal>.
+    See the
+    <ulink
+           url="http://lcweb.loc.gov/z3950/agency/markup/04.html#3.2.2.1.6">
+     Z39.50 standard
+    </ulink>
+    for more details.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>status</literal>
+  </term>
+  <listitem>
+   <para>Displays the values of <literal>lslb</literal>,
+    <literal>ssub</literal> and <literal>mspn</literal>.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>setname</literal>
+  </term>
+  <listitem>
+   <para>Switches named result sets on and off. Default is on.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>cancel</literal>
+  </term>
+  <listitem>
+   <para>Sends a Trigger Resource Control Request to the target.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>format</literal> <replaceable>oid</replaceable>
+  </term>
+  <listitem>
+   <para>Sets the preferred transfer syntax for retrieved records.
+    yaz-client supports all the record syntaxes that currently
+    are registered. See
+    <ulink
+           url="http://lcweb.loc.gov/z3950/agency/defns/oids.html#5">
+     Z39.50 Standard
+    </ulink>
+    for more details. Commonly used records syntaxes include usmarc,
+    sutrs, grs1 and xml.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>elements</literal> <replaceable>e</replaceable>
+  </term>
+  <listitem>
+   <para>Sets the element set name for the records. Many targets support
+    element sets are B (for brief) and F (for full).
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>close</literal>
+  </term>
+  <listitem>
+   <para>Sends a Z39.50 Close APDU and closes connection with the peer
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>querytype</literal> <replaceable>type</replaceable>
+  </term>
+  <listitem>
+   <para>Sets the query type as used by command <literal>find</literal>.
+    The following is supported: <literal>prefix</literal> for 
+    <link linkend="PQF">Prefix Query Notation</link> (Type-1 Query);
+    <literal>ccl</literal> for CCL search (Type-2
+    Query) or <literal>ccl2rpn</literal> for
+    <link linkend="CCL">CCL</link> to RPN conversion (Type-1 Query).
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>attributeset</literal> <replaceable>set</replaceable>
+  </term>
+  <listitem>
+   <para>
+    Sets attribute set OID for prefix queries (RPN, Type-1).
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>refid</literal> <replaceable>id</replaceable>
+  </term>
+  <listitem>
+   <para>Sets reference ID for Z39.50 Request(s).
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>itemorder</literal>
+   <replaceable>type</replaceable> <replaceable>no</replaceable>
+  </term>
+  <listitem>
+   <para>Sends an Item Order Request using the ILL External. 
+    <replaceable>type</replaceable> is either 1 or 2 which corresponds to
+    ILL-Profile 1 and 2 respectively. The <replaceable>no</replaceable>
+    is the Result Set position of the record to be ordered.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
+   <literal>update</literal>
+  </term>
+  <listitem>
+   <para>Sends Item Update Request. This command sends a "minimal"
+    PDU Update to the target supplying the last received record from
+    the target.
+    If no record has been received from the target this command is ignored
+    and nothing is sent to the target.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry><term>
+   <literal>.</literal>
+   <replaceable>filename</replaceable>
+  </term>
+  <listitem>
+   <para>Executes list of commands from
+    file <replaceable>filename</replaceable>, just like source on
+    most UNIX shells.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry><term>
+   <literal>!</literal>
+   <replaceable>args</replaceable>
+  </term>
+  <listitem>
+   <para>Executes command <replaceable>args</replaceable> in subshell
+    using the <literal>system</literal> call.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry><term>
+   <literal>push_commande</literal>
+   <replaceable>command</replaceable>
+  </term>
+  <listitem>
+   <para>The push_command takes another command as its argument.
+    That command is then added to the history information (so
+    you can retrieve it later). The command itself is not
+    executed. This command only works if you have GNU readline/history
+    enabled.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry><term>
+   <literal>set_apdufile</literal>
+   <replaceable>filename</replaceable>
+  </term>
+  <listitem>
+   <para>Sets that APDU should be logged to file
+    <replaceable>filename</replaceable>. This command does the
+    thing as option <literal>-a</literal>.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry><term>
+   <literal>set_marcdump</literal>
+   <replaceable>filename</replaceable>
+  </term>
+  <listitem>
+   <para>Specifies that all retrieved records should be appended ot
+    file <replaceable>filename</replaceable>. This command does the
+    thing as option <literal>-m</literal>.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry><term>
+   <literal>set_cclfields</literal>
+   <replaceable>filename</replaceable>
+  </term>
+  <listitem>
+   <para>Specifies that CCL fields should be read from file
+    file <replaceable>filename</replaceable>. This command does the
+    thing as option <literal>-c</literal>.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry><term>
+   <literal>register_oid</literal>
+   <replaceable>name</replaceable>
+   <replaceable>class</replaceable>
+   <replaceable>OID</replaceable>
+  </term>
+  <listitem>
+   <para>This command allows you to register your own object
+    identifier - so that instead of entering a long dot-notation
+    you can use a short name instead.
+    The <replaceable>name</replaceable> is your
+    name for the OID, <replaceable>class</replaceable> is the
+    class, and <replaceable>OID</replaceable> is the raw OID in
+    dot notation. Class is one <literal>appctx</literal>,
+    <literal>absyn</literal>, <literal>attet</literal>,
+    <literal>transyn</literal>, <literal>diagset</literal>,
+    <literal>recsyn</literal>, <literal>resform</literal>,
+    <literal>accform</literal>, <literal>extserv</literal>,
+    <literal>userinfo</literal>, <literal>elemspec</literal>,
+    <literal>varset</literal>, <literal>schema</literal>,
+    <literal>tagset</literal>, <literal>general</literal>.
+    If you're in doubt use the <literal>general</literal>
+    class.
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+<!-- 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:
+-->
diff --git a/doc/yaz-client.sgml b/doc/yaz-client.sgml
new file mode 100644 (file)
index 0000000..3742846
--- /dev/null
@@ -0,0 +1,130 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+     <!ENTITY yaz-client-commands SYSTEM "yaz-client-commands.xml">
+]>
+<!-- $Id: yaz-client.sgml,v 1.1 2002-09-16 14:16:31 adam Exp $ -->
+<refentry id="yaz-client">
+ <refmeta>
+  <refentrytitle>yaz-client</refentrytitle>
+  <manvolnum>1</manvolnum>
+ </refmeta>
+ <refnamediv>
+  <refname>yaz-client</refname>
+  <refpurpose>Z39.50 client for implementors</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+  <cmdsynopsis>
+   <command>yaz-client</command>
+   <arg choice="opt"><option>-m <replaceable>filename</replaceable></option></arg>
+   <arg choice="opt"><option>-a <replaceable>filename</replaceable></option></arg>
+   <arg choice="opt"><option>-c <replaceable>filename</replaceable></option></arg>
+   <arg choice="opt"><option>-p <replaceable>addr</replaceable></option></arg>
+   <arg choice="opt"><option>-u <replaceable>auth</replaceable></option></arg>
+   <arg choice="opt"><option>-k <replaceable>size</replaceable></option></arg>
+   <arg choice="opt">addr</arg>
+  </cmdsynopsis>
+
+  <cmdsynopsis>
+   <command>yaz-client-ssl</command>
+   <arg rep="repeat" choice="opt"><option>option</option></arg>
+   <arg choice="opt">addr</arg>
+  </cmdsynopsis>
+  
+  <refsect1><title>DESCRIPTION</title>
+   <para>
+    <command>yaz-client</command> is a Z39.50 client (origin) with a
+    simple command line interface that allows you to test behavior and
+    performance of Z39.50 servers (targets).
+   </para>
+   <para>
+    <command>yaz-client-ssl</command> is identical to
+    <command>yaz-client</command> except that it supports SSL transport.
+   </para>
+   <para>
+    If the <replaceable>addr</replaceable> is specified, the client creates
+    a connection to the Z39.50 target at the address.
+   </para>
+  </refsect1>
+  <refsect1>
+   <title>OPTIONS</title>
+   <variablelist>
+    <varlistentry>
+     <term>-m <replaceable>filename</replaceable></term>
+     <listitem><para>
+       If specified, retrieved MARC (ISO2709) records will
+       be appended to the file given.
+      </para></listitem>
+    </varlistentry>
+    <varlistentry>
+     <term>-a <replaceable>filename</replaceable></term>
+     <listitem><para>
+       If specified, logging of protocol packages will be appended
+       file given. The special filename <literal>-</literal>
+       (dash) denotes standard output.
+      </para></listitem>
+    </varlistentry>
+    <varlistentry>
+     <term>-u <replaceable>auth</replaceable></term>
+     <listitem><para>
+       If specified, the <replaceable>auth</replaceable> string
+       will be used for authentication.
+      </para></listitem>
+    </varlistentry>
+    <varlistentry>
+     <term>-c <replaceable>filename</replaceable></term>
+     <listitem><para>
+       If specified, CCL configuration will be read from
+       the file given.
+      </para></listitem>
+    </varlistentry>
+    <varlistentry>
+     <term>-p <replaceable>addr</replaceable></term>
+     <listitem><para>
+       If specified, the client will use the proxy at the address
+       given.
+      </para></listitem>
+    </varlistentry>
+   </variablelist>
+  </refsect1>
+  <refsect1>
+   <title>COMMANDS</title>
+   <para>
+    The YAZ client accepts the following commands.
+   </para>
+   &yaz-client-commands;
+   </refsect1>
+  <refsect1><title>FILES</title>
+   <para>
+    <filename>yaz-&lt;version&gt;/client/client.c</filename>
+   </para>
+  </refsect1>
+  <refsect1><title>SEE ALSO</title>
+   <para>yaz(7)</para>
+   <para>
+    Section "The YAZ Client" in the YAZ manual.
+   </para>
+   <para id="PQF">
+    Section "Prefix Query Format" in the YAZ manual.
+   </para>
+   <para id="CCL">
+    Section "Common Command Language" in the YAZ manual.
+   </para>
+  </refsect1>
+</refentry>
+
+<!-- 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:nil
+sgml-local-catalogs: nil
+sgml-namecase-general:t
+End:
+-->
diff --git a/doc/yaz-config.sgml b/doc/yaz-config.sgml
new file mode 100644 (file)
index 0000000..6c98729
--- /dev/null
@@ -0,0 +1,137 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!-- $Id: yaz-config.sgml,v 1.1 2002-09-16 14:16:31 adam Exp $ -->
+<refentry id="yaz-config">
+ <refmeta>
+  <refentrytitle>yaz-config</refentrytitle>
+  <manvolnum>1</manvolnum>
+ </refmeta>
+ <refnamediv>
+  <refname>yaz-config</refname>
+  <refpurpose>Script to get information about YAZ.
+ </refnamediv>
+ <refsynopsisdiv>
+  <cmdsynopsis>
+   <command>yaz-config</command>
+   <arg choice="opt"><option>--prefix[=<replaceable>DIR</replaceable>]</option></arg>
+   <arg choice="opt"><option>--version</option></arg>
+   <arg choice="opt"><option>--libs</option></arg>
+   <arg choice="opt"><option>--lalibs</option></arg>
+   <arg choice="opt"><option>--cflags</option></arg>
+   <arg choice="opt"><option>--tabs</option></arg>
+   <arg choice="opt" rep="repeat">libraries</arg>
+  </cmdsynopsis>
+ </refsynopsisdiv>
+ <refsect1><title>DESCRIPTION</title>
+  <para>
+   <command>yaz-config</command> is a script that returns information
+   that your own software should use to build software that uses YAZ.
+  </para>
+
+  <para>
+   The following libraries are supported:
+  </para>
+
+  <variablelist>
+   <varlistentry>
+    <term>threads</term>
+    <listitem><para>
+      Use the threaded version of YAZ.
+     </para></listitem>
+   </varlistentry>
+   <varlistentry>
+    <term>ssl</term>
+    <listitem><para>
+      Use YAZ with SSL support.
+     </para></listitem>
+   </varlistentry>
+  </variablelist>
+  
+ </refsect1>
+ <refsect1><title>OPTIONS</title>
+  
+  <variablelist>
+   <varlistentry>
+    <term>--prefix[=<replaceable>DIR</replaceable>]</term>
+    <listitem><para>
+      Returns prefix of YAZ or assume a different one if DIR is
+      specified.
+     </para></listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term>--version</term>
+    <listitem><para>
+      Returns version of YAZ.
+     </para></listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term>--libs</term>
+    <listitem><para>
+      Library specification be used when using YAZ.
+     </para></listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term>--lalibs</term>
+    <listitem><para>
+      Return library specification.
+     </para></listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term>--cflags</term>
+    <listitem><para>
+      Return C Compiler flags.
+     </para></listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term>--tabs</term>
+    <listitem><para>
+      Return directory of YAZ tables.
+     </para></listitem>
+   </varlistentry>
+
+  </variablelist>
+ </refsect1>
+ <refsect1><title>FILES</title>
+  <para>
+   <filename><replaceable>prefix</replaceable>/bin/yaz-config</filename>
+  </para>
+  <para>
+   <filename><replaceable>prefix</replaceable>/lib/libyaz*.a</filename>
+  </para>
+  <para>
+   <filename><replaceable>prefix</replaceable>/include/yaz/*.h</filename>
+  </para>
+  </refsect1>
+ <refsect1><title>SEE ALSO</title>
+  <para>
+   yaz(7)
+  </para>
+  <para>
+   Section "How to make apps using YAZ on UNIX" in the YAZ manual.
+  </para>
+ </refsect1>
+</refentry>
+
+<!-- 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:nil
+sgml-local-catalogs: nil
+sgml-namecase-general:t
+End:
+-->
diff --git a/doc/yaz-man.sgml b/doc/yaz-man.sgml
new file mode 100644 (file)
index 0000000..8f5bdce
--- /dev/null
@@ -0,0 +1,94 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!-- $Id: yaz-man.sgml,v 1.1 2002-09-16 14:16:31 adam Exp $ -->
+<refentry id="yaz">
+ <refmeta>
+  <refentrytitle>yaz</refentrytitle>
+  <manvolnum>7</manvolnum>
+ </refmeta>
+ <refnamediv>
+  <refname>YAZ</refname>
+  <refpurpose>Z39.50 toolkit.
+ </refnamediv>
+ <refsynopsisdiv>
+  <cmdsynopsis>
+   <command>YAZ</command>
+  </cmdsynopsis>
+ </refsynopsisdiv>
+ <refsect1><title>DESCRIPTION</title>
+  <para>
+   YAZ is a C/C++ programmer's toolkit supporting the development
+   of Z39.50v3 clients and servers. The YAZ toolkit offers
+   several different levels of acess to the ISO23950/Z39.50 and
+   ILL protocols. The level that you need to use depends
+   on your requirements, and the role (server of client) that you want
+   to implement.
+  </para>
+ </refsect1>
+
+ <refsect1><title>COPYRIGHT</title>
+  <para>
+   Copyright (c) 1995-2002, Index Data.
+  </para>
+  <para>
+   Permission to use, copy, modify, distribute, and sell this software and
+   its documentation, in whole or in part, for any purpose, is hereby granted,
+   provided that:
+  </para>
+  <para>
+   1. This copyright and permission notice appear in all copies of the
+   software and its documentation. Notices of copyright or attribution
+   which appear at the beginning of any file must remain unchanged.
+  </para>
+  <para>
+   2. The names of Index Data or the individual authors may not be used to
+   endorse or promote products derived from this software without specific
+   prior written permission.
+  </para>
+  
+  <para>
+   THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+   WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+   IN NO EVENT SHALL INDEX DATA BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+   INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR
+   NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+   LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+   OF THIS SOFTWARE.
+  </para>
+ </refsect1>
+ <refsect1><title>SEE ALSO</title>
+  <para><command>yaz-client(1)</command>, 
+   <command>yaz-ztest(8)</command>, 
+   <command>yaz-config(1)</command>
+  </para>
+  <para>YAZ manual (
+   <filename><replaceable>prefix</replaceable>/share/yaz/doc</filename>)
+  </para>
+  <para>
+   <ulink url="http://www.indexdata.dk/yaz/">YAZ home page</ulink>.
+  </para>
+  <para>
+   <ulink url="http://www.loc.gov/z3950/agency/">Z39.50 Maintenance
+    Agency Page</ulink>.
+  </para>
+</refentry>
+
+<!-- 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:nil
+sgml-local-catalogs: nil
+sgml-namecase-general:t
+End:
+-->
diff --git a/doc/yaz-ztest.sgml b/doc/yaz-ztest.sgml
new file mode 100644 (file)
index 0000000..a1c4471
--- /dev/null
@@ -0,0 +1,101 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+     <!ENTITY ztest-options SYSTEM "ztest-options.xml">
+]>
+<!-- $Id: yaz-ztest.sgml,v 1.1 2002-09-16 14:16:31 adam Exp $ -->
+<refentry id="yaz-ztest">
+ <refmeta>
+  <refentrytitle>yaz-ztest</refentrytitle>
+  <manvolnum>8</manvolnum>
+ </refmeta>
+ <refnamediv>
+  <refname>yaz-ztest</refname>
+  <refpurpose>Z39.50 Test Server</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+  <cmdsynopsis>
+   <command>yaz-ztest</command>
+   <arg choice="opt"><option>-a <replaceable>file</replaceable></option></arg>
+   <arg choice="opt"><option>-v <replaceable>level</replaceable></option></arg>
+   <arg choice="opt"><option>-l <replaceable>file</replaceable></option></arg>
+   <arg choice="opt"><option>-u <replaceable>uid</replaceable></option></arg>
+   <arg choice="opt"><option>-c <replaceable>config</replaceable></option></arg>
+   <arg choice="opt"><option>-t <replaceable>minutes</replaceable></option></arg>
+   <arg choice="opt"><option>-k <replaceable>kilobytes</replaceable></option></arg>
+   <arg choice="opt"><option>-d <replaceable>daemon</replaceable></option></arg>
+   <arg choice="opt"><option>-ziST1</option></arg>
+   <arg choice="opt"><option>-w <replaceable>dir</replaceable></option></arg>
+   <arg choice="opt" rep="repeat">listener-spec</arg>
+  </cmdsynopsis>
+
+  <cmdsynopsis>
+   <command>yaz-ztest-ssl</command>
+   <arg rep="repeat" choice="opt"><option>option</option></arg>
+   <arg choice="opt" rep="repeat">addr</arg>
+  </cmdsynopsis>
+
+  <refsect1><title>DESCRIPTION</title>
+   <para>
+    <command>yaz-ztest</command> is a Z39.50 test server. 
+    The server acts as a real Z39.50 server but does not use a database.
+    It returns a random hit count and returns a subset of a few build-in
+    records.
+   </para>
+   <para>
+    <command>yaz-ztest-ssl</command> is identical to
+    <command>yaz-ztest</command> except that it supports SSL transport.
+   </para>
+   <para>
+    The <replaceable>listener-spec</replaceable> 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:
+    <screen>
+     hostname | IP-number [ : portnumber ]
+    </screen>
+   </para>
+   <para>
+    For UNIX local socket the address is the filename of the local socket.
+   </para>
+  </refsect1>
+  <refsect1>
+   <title>OPTIONS</title>
+   &ztest-options;
+  </refsect1>
+  <refsect1><title>FILES</title>
+   <para>
+    <filename>yaz-&lt;version&gt;/ztest/yaz-ztest.c</filename>
+   </para>
+   <para>
+    <filename>yaz-&lt;version&gt;/include/yaz/backend.h</filename>
+   </para>
+  </refsect1>
+  <refsect1><title>SEE ALSO</title>
+   <para>
+    yaz(7)
+   </para>
+   <para>
+    Section "Generic server" in the YAZ manual.
+   </para>
+  </refsect1>
+</refentry>
+
+<!-- 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:nil
+sgml-local-catalogs: nil
+sgml-namecase-general:t
+End:
+-->
diff --git a/doc/yaz.sgml b/doc/yaz.sgml
deleted file mode 100644 (file)
index 8cb4577..0000000
+++ /dev/null
@@ -1,3866 +0,0 @@
-<!doctype linuxdoc system>
-<article>
-<title>YAZ User's Guide and Reference
-<author><htmlurl url="http://www.indexdata.dk/" name="Index Data">, <tt><htmlurl url="mailto:info@indexdata.dk" name="info@indexdata.dk"></>
-<date>$Revision: 1.10 $
-<abstract>
-This document is the programmer's guide and reference to the YAZ
-package. YAZ is a compact toolkit that provides access to the
-Z39.50/SR protocol, as well as a set of higher-level tools for
-implementing the server and client roles, respectively.
-The documentation can be used on its own, or as a reference when looking
-at the example applications provided with the package.
-</abstract>
-
-<toc>
-
-<sect>Introduction
-
-<p>
-The <bf/YAZ/ toolkit offers several different levels of access to the
-Z39.50 and SR protocols. The level that you need to use depends on
-your requirements, and the role (server or client) that you
-want to implement.
-
-The basic level, which is independent of the role, consists of three
-primary interfaces:
-
-<itemize>
-<item><bf/ASN/, which provides a C representation of the Z39.50/SR protocol
-packages (PDUs).
-<item><bf/ODR/, which encodes and decodes the packages according to the BER
-specification.
-<item><bf/COMSTACK/, which exchanges the encoded packages with a peer process
-over a network.
-</itemize>
-
-The ASN module represents the ASN.1 definition of the
-SR/Z39.50 protocol. It establishes a set of type and
-structure definitions, with one structure for each of the top-level
-PDUs, and one structure or type for each of the contained ASN.1 types.
-For primitive types, or other types that are defined by the ASN.1
-standard itself (such as the EXTERNAL type), the C representation is provided
-by the <bf/ODR/ (Open Data Representation) subsystem.
-
-<bf/ODR/ is a basic mechanism for representing an
-ASN.1 type in the C programming language, and for implementing BER
-encoders and decoders for values of that type. The types defined in
-the <bf/ASN/
-module generally have the prefix <tt/Z_/, and a suffix corresponding to
-the name of the type in the ASN.1
-specification of the protocol (generally Z39.50-1995). In the case of
-base types (those originating in the ASN.1 standard itself), the prefix
-<tt/Odr_/ is sometimes seen. Either way, look for
-the actual definition in either <tt/proto.h/ (for the types from the
-protocol), <tt/odr.h/ (for the primitive ASN.1 types, or <tt/odr_use.h/ (for the
-ASN.1 <it/useful/ types). The <bf/ASN/ library also provides functions (which
-are, in turn, defined using <bf/ODR/ primitives) for encoding and decoding data
-values. Their general form is
-
-<tscreen><verb>
-int z_xxx(ODR o, Z_xxx **p, int optional, const char *name);
-</verb></tscreen>
-
-(note the lower-case &dquot;z&dquot; in the function name)
-
-<it>
-NOTE: If you are using the premade definitions of the <bf/ASN/ module, and
-you are not adding new protocol of your own, the only parts of ODR
-that you need to worry about are documented in section
-<ref id="odr-use" name="Using ODR">.
-</it>
-
-When you have created a BER-encoded buffer, you can use the <bf/COMSTACK/
-subsystem to transmit (or receive) data over the network. The <bf/COMSTACK/
-module provides simple functions for establishing a connection
-(passively or actively, depending on the role of your application),
-and for exchanging BER-encoded PDUs over that connection. When you
-create a connection endpoint, you need to specify what transport to
-use (OSI or TCP/IP), and which protocol you want to use (SR or
-Z39.50). For the remainer of the connection's lifetime, you don't have
-to worry about the underlying transport protocol at all - the <bf/COMSTACK/
-will ensure that the correct mechanism is used.
-
-We call the combined interfaces to <bf/ODR/, <bf/ASN/, and <bf/COMSTACK/ the service
-level API. It's the API that most closely models the Z39.50/SR
-service/protocol definition, and it provides unlimited access to all
-fields and facilities of the protocol definitions.
-
-The reason that the <bf/YAZ/ service-level API is a conglomerate of the
-APIs from three different submodules is twofold. First, we wanted to allow the
-user a choice of different options for each major task. For instance,
-if you don't like the protocol API provided by <bf/ODR//<bf/ASN/, you
-can use SNACC or BERUtils instead, and still have the benefits of the
-transparent transport approach of the <bf/COMSTACK/ module. Secondly,
-we realise that you may have to fit the toolkit into an existing
-event-processing structure, in a way that
-is incompatible with the <bf/COMSTACK/ interface or some other part of <bf/YAZ/.
-
-<sect>Compilation and Installation
-
-<p>
-The latest version of the software will generally be found at
-
-<tscreen><verb>
-<htmlurl url="http://ftp.indexdata.dk/pub/yaz/" name="http://ftp.indexdata.dk/pub/yaz/">
-</verb></tscreen>
-
-We have tried our best to keep the software portable, and on many
-platforms, you should be able to compile everything with little or no changes.
-So far, the software has been ported
-to the following platforms with little or no difficulties.
-
-<itemize>
-<item>Unix systems
-<itemize>
-<item>HP/UX
-<item>SunOS/Solaris
-<item>DEC Unix
-<item>Linux
-<item>IBM AIX
-<item>Data General DG/UX (with some CFLAGS tinkering)
-<item>SGI/IRIX
-<item>DDE Supermax
-</itemize>
-<item>Non-unix systems
-<itemize>
-<item>Apple Macintosh (using the Codewarrior programming environment and the
-GUSI socket libraries)
-<item>MS Windows 95/NT (Win32)
-<item>IBM AS/400
-</itemize>
-</itemize>
-
-If you move the software to other platforms, we'd be grateful if you'd
-let us know about it. If you run into difficulties, we will try to help if we
-can, and if you solve the problems, we would be happy to
-include your fixes in the next release. So far, we have mostly avoided
-&num;ifdefs for individual platforms, and we'd like to keep it that
-way as far as it makes sense.
-
-We maintain a mailing-list for the purpose of announcing new releases and
-bug-fixes, as well as general discussion. Subscribe by sending mail to
-<tt/yaz-request@indexdata.dk/. General questions and problems can be
-directed at <tt/yaz-help@indexdata.dk/, or the address given at the top
-of this document.
-
-<sect1>UNIX
-
-<p>
-Note that if your system doesn't have a native ANSI C compiler, you may
-have to acquire one separately. We recommend gcc.
-
-For UNIX we use GNU configure to create Makefiles for YAZ.
-Generally it should be sufficient to run configure without options:
-
-<tscreen><verb>
-./configure
-</verb></tscreen>
-
-The configure script attempts to use use the C compiler specified by
-the <tt/CC/ environment variable. If not set, GNU C will be used
-if it is available. The <tt/CFLAGS/ environment variable holds options
-to be passed to the C compiler. If you're using Bourne-compatible shell
-you may pass something like this to use a particular C compiler with
-optimization enabled:
-<tscreen><verb>
-  CC=/opt/ccs/bin/cc CFLAGS=-O ./configure
-</verb></tscreen>
-
-To customize <bf/YAZ/ the configure script also accepts a set of options.
-The most important are:
-
-<descrip>
-<tag><tt>-</tt><tt>-prefix </tt>path</tag> Specifies installation prefix. This is
-only needed if you run <tt>make install</tt> later to perform a
-"system" installation. The prefix is <tt>/usr/local</tt> if not
-specified.
-
-<tag><tt>-</tt><tt>-enable-comp </tt></tag> YAZ will be built using
-the ASN.1 compiler for YAZ (default). If you wish to use the
-old decoders (in sub directory asn) use <tt>--disable-comp</tt> instead.
-
-<tag><tt>-</tt><tt>-enable-threads</tt></tag> YAZ will be built using
-POSIX threads. Specifically, <tt>_REENTRANT</tt> will be defined
-during compilation.
-</descrip>
-
-When configured, build the software by typing:
-<tscreen><verb>
-  make
-</verb></tscreen>
-
-The following files are generated by the make process:
-<descrip>
-<tag><tt>lib/libyaz.a</tt></tag> The <bf/YAZ/ programmers' library.
-
-<tag><tt>ztest/yaz-ztest</tt></tag> A test Z39.50 server.
-
-<tag><tt>client/yaz-client</tt></tag> A command mode Z39.50 client.
-
-<tag><tt>yaz-config</tt></tag> A Bourne-shell script that holds build
-settings for <bf/YAZ/.
-
-<tag><tt>yaz-comp</tt></tag> The ASN.1 compiler for YAZ. Requires the
-Tcl Shell, tclsh, in current path to work.
-
-</descrip>
-
-If you wish to install <bf/YAZ/ in system directories such as /usr/local/bin,
-/usr/local/lib) you can type:
-
-<tscreen><verb>
-  make install
-</verb></tscreen>
-
-You probably need to have root access in order to perform this.
-You must specify the <tt>--prefix</tt> option for configure if you
-going to install in anything but /usr/local/.
-
-If you wish to perform an un-installation of YAZ you use:
-
-<tscreen><verb>
-  make uninstall
-</verb></tscreen>
-
-This will only work if you haven't reconfigured YAZ (and therefore
-changed installation prefix). Note that uninstall will not
-remove directories created by make install, e.g.
-<tt>/usr/local/include/yaz</tt>.
-
-<sect1>WIN32
-
-<p>
-<bf/YAZ/ is shipped with "makefiles" for the NMAKE tool that comes
-with Visual C++.
-
-Start an MS-DOS prompt and switch the sub directory <tt>WIN</tt> where
-the file <tt>makefile</tt> is located. Customize the installation
-by editing the <tt>makefile</tt> file (for example by using notepad).
-
-The following summarises the most important settings in that file:
-
-<descrip>
-<tag><tt>NEW_Z3950</tt></tag> If 1, the auto-generated decoder/encoders
-for Z39.50 as written by the ASN.1 compiler will be used. If 0, the old
-decoders for Z39.50 will be used. Note, when 1, the setting TCL should
-point to the Tcl shell on your system.
-<tag><tt>DEBUG</tt></tag> If set to 1, the software is
-compiled with debugging libraries. If set to 0, the software
-is compiled with release (non-debugging) libraries.
-</descrip>
-
-When satisfied with the settings in the makefile type
-<tscreen><verb>
-nmake
-</verb></tscreen>
-
-The following is generated upon successful compilation:
-<descrip>
-<tag><tt>bin/yaz.dll</tt></tag> A multithreaded DLL with everything
-except the frontend server library.
-<tag><tt>lib/yaz.lib</tt></tag> An import library for <tt>yaz.dll</tt>.
-<tag><tt>lib/server.lib</tt></tag> The frontend server library.
-<tag><tt>bin/yaz-ztest.exe</tt></tag> A test Z39.50 server.
-<tag><tt>bin/yaz-client.exe</tt></tag> A command mode Z39.50 client.
-</descrip>
-
-<sect>Using the Yaz-client
-
-<p>
-yaz-client is a linemode Z39.50 client. It supports a fair amount of the
-functionality of Z39.50-1995 standard, but some things you need to enable or
-disable by recompilation. Its primary purpose is to exercise the
-package, and verify that the protocol works OK.
-
-It can be started by typing
-<tscreen><verb>
-  yaz-client [-m &lt;marclog&gt;] [ -a &lt;apdulog&gt;] tcp:&lt;hostname&gt;:&lt;port&gt;[/&lt;database&gt;]
-</verb></tscreen>
-at the UNIX prompt, to connect to a Z39.50 server.
-
-The options are
-<itemize>
-<item><bf/-m/ Turns dumping of the raw MARC records on in ISO 2709 format.
-Marclog is the filename to write to.
-<item><bf/-a/ Turns dumping of the APDU on. Apdulog is the filename to
-write to. If apdulog is "-" the APDU is written to the screen.
-</itemize>
-
-In order to connect to Index Data's test Z39.50 server on
-bagel.indexdata.dk, port 210 and with the database name marc, one would
-have to type
-<tscreen><verb>
-    yaz-client tcp:bagel.indexdata.dk:210/marc
-</verb></tscreen>
-In order to also dump the APDU to the screen you would have to write
-<tscreen><verb>
-    yaz-client -a - tcp:bagel.indexdata.dk:210/marc
-</verb></tscreen>
-Use '?' to get a list of the available commands.
-
-The commands are (the letters in parenthesis are short names for the commands):
-<descrip>
-<tag/open (o)/Opens a connection to a server. The syntax is the same as described above for connecting from the command line.
-<p>Syntax:
-<tscreen><verb>
-open ('tcp'|'osi')':'[&lt;tsel&gt;'/']&lt;host&gt;[':'&lt;port&gt;]
-</verb></tscreen>
-<tag/quit (q)/
-Ends yaz-client
-<p>Syntax:
-<tscreen><verb>
-quit
-</verb></tscreen>
-<tag/find (f)/
-Sends the RPN query to the server.
-<p>Syntax:
-<tscreen><verb>
-find &lt;query&gt;
-</verb></tscreen>
-<tag/delete/
-Deletes a result set on the server.
-<p>Syntax:
-<tscreen><verb>
-delete &lt;setname&gt;
-</verb></tscreen>
-<tag/base/
-Sets the name of the database to search in if it wasn't already set in the
-connect string. More than one database can be searched in parallel by writing
-several databases (hosted on the same server) separated by white space.
-<p>Syntax:
-<tscreen><verb>
-base &lt;base-name&gt;
-</verb></tscreen>
-<tag/show (s)/
-Shows a record. If no record number is specified the next record in the result set is shown.
-<p>Syntax:
-<tscreen><verb>
-show &lt;rec#&gt;['+'&lt;#recs&gt;['+'&lt;setname&gt;]]
-</verb></tscreen>
-<tag/scan/
-Scans the database index for a term. The syntax resembles the syntax for <bf/find/.
-If you want to scan for the word <it/water/ you would write
-<tscreen><verb>
-scan water
-</verb></tscreen>
-but if you want to scan only in, say the title field, you would write
-<tscreen><verb>
-scan @attr 1=4 water
-</verb></tscreen>
-<p>Syntax:
-<tscreen><verb>
-scan <term>
-</verb></tscreen>
-<tag/sort/
-Sorts a result set. The sort command takes a sequence of sort specifications. A sort
-specification holds a field (sort criteria) and is followed by flags.
-If the sort criteria includes = it is assumed that the sort SortKey
-is of type sortAttributes using Bib-1. The integer before the = is
-the attribute type and the integer following the = is the attribute
-value. If no = is in the SortKey it is treated as a sortfield-type
-of type InternationalString. Flags observed are
-<itemize>
-    <item><bf/s/ (sort case sensitive)
-    <item><bf/i/ (sort case insensitive), &lt; (ascending), &gt; (descending).
-</itemize>
-Eg.:
-<verb>
-   1=4   i&lt;                  (use is title, insensitive, ascending).
-   Title s&gt;                  (String Title, sensitive, descending).
-</verb>
-<p>Syntax:
-<tscreen><verb>
-sort &lt;sortkey&gt; &lt;flag&gt; &lt;sortkey&gt; &lt;flag&gt; ...
-</verb></tscreen>
-<tag/sort+/
-Same as <bf/sort/ but stores the sorted result set in a new result set.
-<p>Syntax:
-<tscreen><verb>
-sort+ &lt;sortkey&gt; &lt;flag&gt; &lt;sortkey&gt; &lt;flag&gt; ...
-</verb></tscreen>
-<tag/authentication/
-Sets up a authentication string if a server requires authentication. The authentication string is first
-sent to the server when the <bf/open/ command is issued.
-<p>Syntax:
-<tscreen><verb>
-authentication &lt;acctstring&gt;
-</verb></tscreen>
-<tag/lslb/
-Sets the limit for when no records should be returned together with the search result.
-See the <htmlurl url="http://lcweb.loc.gov/z3950/agency/markup/04.html#3.2.2.1.6" name="Z39.50 standard">
-for more details.
-<p>Syntax:
-<tscreen><verb>
-lslb &lt;largeSetLowerBound&gt;
-</verb></tscreen>
-<tag/ssub/
-Sets the limit for when all records should be returned with the search result.
-See the <htmlurl url="http://lcweb.loc.gov/z3950/agency/markup/04.html#3.2.2.1.6" name="Z39.50 standard">
-for more details.
-<p>Syntax:
-<tscreen><verb>
-ssub &lt;smallSetUpperBound&gt;
-</verb></tscreen>
-<tag/mspn/
-Sets the number of records should be returned if the number of records in the
-result set is between the values of <bf/lslb/ and <bf/ssub/.
-See the <htmlurl url="http://lcweb.loc.gov/z3950/agency/markup/04.html#3.2.2.1.6" name="Z39.50 standard">
-for more details.
-<p>Syntax:
-<tscreen><verb>
-mspn &lt;mediumSetPresentNumber&gt;
-</verb></tscreen>
-<tag/status/
-Displays the values of <bf/lslb/, <bf/ssub/ and <bf/mspn/.
-<p>Syntax:
-<tscreen><verb>
-status
-</verb></tscreen>
-<tag/setname/
-Switches named result sets on and off. Default is on.
-<p>Syntax:
-<tscreen><verb>
-setnames
-</verb></tscreen>
-<tag/cancel/
-Sends a trigger resource ctrl cancel to the server.
-<p>Syntax:
-<tscreen><verb>
-cancel
-</verb></tscreen>
-<tag/format/
-Sets the preferred transfer syntax the records should be returned in.
-yaz-client supports all the record syntaxes that corrently are registered
-with the  (see the <htmlurl url="http://lcweb.loc.gov/z3950/agency/defns/oids.html#5" name="Z39.50 Agency"> for more details) including usmarc, sutrs, GRS1 and XML
-<p>Syntax:
-<tscreen><verb>
-format &lt;recordsyntax&gt;
-</verb></tscreen>
-<tag/schema/
-Sets the preferred schema the records should be returned in.
-<p>Syntax:
-<tscreen><verb>schema &lt;schema&gt;
-</verb></tscreen>
-<tag/elements/
-Sets the element set name for the records.
-<itemize>
-<item><bf/b/ Brief
-<item><bf/f/ Full
-<item>Any other element set name the server may support
-</itemize>
-<p>Syntax:
-<tscreen><verb>
-elements &lt;elementSetName&gt;
-</verb></tscreen>
-<tag/close/
-Sends a close request.
-<p>Syntax:
-<tscreen><verb>close
-</verb></tscreen>
-<tag/querytype/
-Sets the query type. Default is prefix.
-<itemize>
-<item><bf/prefix/ RPN query.
-<item><bf/CCL/ CCL (Common Command Language) query.
-<item><bf/ CCL2RPN/A CCL variant that is interpreted on the client side
-which allows you to specify field names. See section <ref id="CCL" name="Common Command Language"> for more details.
-</itemize>
-<p>Syntax:
-<tscreen><verb>
-querytype &lt;type&gt;
-</verb></tscreen>
-<tag/attributeset/
-Specifies the default attribute set in the query. Default is Bib1
-(see the <htmlurl url="http://lcweb.loc.gov/z3950/agency/defns/bib1.html" name="Z39.50 Agency">). This command applies only to the prefix querytype. Note that
-you can also specify the attribute set directly in the RPN query.
-<p>Syntax:
-<tscreen><verb>
-attributeset &lt;attrset&gt;
-</verb></tscreen>
-<tag/refid/
-Sets a reference id for a request to be send to the server.
-See the <htmlurl url="http://lcweb.loc.gov/z3950/agency/markup/08.html#3.4" name="Z39.50 standard">
-for more details.
-<p>Syntax:
-<tscreen><verb>
-refid <id>
-</verb></tscreen>
-<tag/itemorder/
-Sends an itemorder to the server. Only the required fields are implemented.
-<p>Syntax:
-<tscreen><verb>
-itemorder 1|2 &lt;item&gt;
-</verb></tscreen>
-<tag/update/
-Sends an item update to the server. This feature is not fully implemented yet.
-<p>Syntax:
-<tscreen><verb>
-update &lt;item&gt;
-</verb></tscreen>
-</descrip>
-<sect1>Searching with yaz-client
-<p>
-The simplest form of a RPM query in yaz-client would be something like
-<tscreen><verb>
-    f knuth
-</verb></tscreen>
-or
-<tscreen><verb>
-    f "donald knuth"
-</verb></tscreen>
-This leaves it up to the server what fields to search but most servers will search
-in all fields. Some servers does not support this feature though, and require that
-a search attribute is defined. This would look something like this in yaz-client:
-<tscreen><verb>
-    f @attr 1=4 computer
-</verb></tscreen>
-where we search in the title field. If we want to search in the author field <bf/and/
-in the title field, and in the title field using right truncation it could look something like this:
-<tscreen><verb>
-    f @and @attr 1=1003 knuth @attr 1=4 @attr 5=1 computer
-</verb></tscreen>
-Finally using a mix of Bib-1 and GILS attributes could look something like this:
-<tscreen><verb>
-    f @attrset Bib-1 @and @attr GILS 2=2008 Washington @attr 1=21 weather
-</verb></tscreen>
-For the full spacifiction of the RPN query language please see the section <ref id="PQF" name="Prefix Query Format">.
-
-<sect>The ASN Module
-
-<sect1>Introduction
-
-<p>
-The <bf/ASN/ module provides you with a set of C struct definitions for the
-various PDUs of the protocol, as well as for the complex types
-appearing within the PDUs. For the primitive data types, the C
-representation often takes the form of an ordinary C language type,
-such as <tt/int/. For ASN.1 constructs that have no direct
-representation in C, such as general octet strings and bit strings,
-the <bf/ODR/ module (see section <ref id="odr" name="ODR">) provides auxiliary
-definitions.
-
-<sect1>Preparing PDUs
-
-<p>
-A structure representing a complex ASN.1 type doesn't in itself contain the
-members of that type. Instead, the structure contains <it/pointers/ to
-the members of the type. This is necessary, in part, to allow a mechanism for
-specifying which of the optional structure (SEQUENCE) members are
-present, and which are not. It follows that you will need to somehow
-provide space for the individual members of the structure, and
-set the pointers to refer to the members.
-
-The conversion routines don't care how you allocate and maintain your
-C structures - they just follow the pointers that you provide.
-Depending on the complexity of your application, and your personal
-taste, there are at least three different approaches that you may take
-when you allocate the structures.
-
-<itemize>
-<item>
-You can use static or automatic local variables in the function that
-prepares the PDU. This is a simple approach, and it provides the most
-efficient form of memory management. While it works well for flat
-PDUs like the InitReqest, it will generally not be sufficient for say,
-the generation of an arbitrarily complex RPN query structure.
-<item>
-You can individually create the structure and its members using the
-<tt/malloc/(2) function. If you want to ensure that the data is freed when
-it is no longer needed, you will have to define a function that
-individually releases each member of a structure before freeing the
-structure itself.
-<item>
-You can use the <tt/odr_malloc()/ function (see section <ref
-id="odr-use"
-name="Using ODR"> for details). When you use <tt/odr_malloc()/, you can release
-all of the
-allocated data in a single operation, independent of any pointers and
-relations between the data. <tt/odr_malloc()/ is based on a
-&dquot;nibble-memory&dquot;
-scheme, in which large portions of memory are allocated, and then
-gradually handed out with each call to <tt/odr_malloc()/. The next time you
-call <tt/odr_reset()/, all of the memory allocated since the last call is
-recycled for future use (actually, it is placed on a free-list).
-<item>
-You can combine all of the methods described here. This will often be
-the most practical approach. For instance, you might use <tt/odr_malloc()/ to
-allocate an entire structure and some of its elements, while you leave
-other elements pointing to global or per-session default variables.
-</itemize>
-
-The <bf/ASN/ module provides an important aid in creating new PDUs. For
-each of the PDU types (say, <tt/Z_InitRequest/), a function is provided
-that allocates and initializes an instance of that PDU type for you.
-In the case of the InitRequest, the function is simply named
-<tt/zget_InitRequest()/, and it sets up reasonable default value for all of
-the mandatory members. The optional members are generally initialized to null
-pointers. This last aspect is very important: it ensures that if the
-PDU definitions are extended after you finish your implementation
-(to accommodate
-new versions of the protocol, say), you won't get into trouble with
-uninitialized pointers in your structures. The functions use
-<tt/odr_malloc()/ to
-allocate the PDUs and its members, so you can free everything again with a
-single call to <tt/odr_reset()/. We strongly recommend that you use the
-<tt/zget_*/
-functions whenever you are preparing a PDU (in a C++ API, the
-<tt/zget_/
-functions would probably be promoted to constructors for the
-individual types).
-
-The prototype for the individual PDU types generally look like this:
-
-<tscreen><verb>
-Z_<type> *zget_<type>(ODR o);
-</verb></tscreen>
-
-eg.:
-
-<tscreen><verb>
-Z_InitRequest *zget_InitRequest(ODR o);
-</verb></tscreen>
-
-The <bf/ODR/ handle should generally be your encoding stream, but it
-needn't be.
-
-As well as the individual PDU functions, a function <tt/zget_APDU()/ is
-provided, which allocates a toplevel Z-APDU of the type requested:
-
-<tscreen><verb>
-Z_APDU *zget_APDU(ODR o, int which);
-</verb></tscreen>
-
-The <tt/which/ parameter is (of course) the discriminator belonging to the
-<tt/Z_APDU/ CHOICE type. All of the interface described here is provided by
-the <bf/ASN/ module, and you access it through the <tt/proto.h/ header file.
-
-<sect1>Object Identifiers<label id="oid">
-
-<p>
-When you refer to object identifiers in your application, you need to
-be aware that SR and Z39.50 use two different set of OIDs to refer to
-the same objects. To handle this easily, <bf/YAZ/ provides a utility module
-to <bf/ASN/ which provides an internal representation of the OIDs used in
-both protocols. Each oid is described by a structure:
-
-<tscreen><verb>
-typedef struct oident
-{
-    enum oid_proto proto;
-    enum oid_class class;
-    enum oid_value value;
-    int oidsuffix[OID_SIZE];
-    char *desc;
-} oident;
-</verb></tscreen>
-
-The <tt/proto/ field can be set to either <tt/PROTO_SR/ or
-<tt/PROTO_Z3950/. The <tt/class/ might be, say, <tt/CLASS_RECSYN/, and the
-<tt/value/ might be <tt/VAL_USMARC/ for the USMARC record format. Functions
-
-<tscreen><verb>
-int *oid_ent_to_oid(struct oident *ent, int *dst);
-struct oident *oid_getentbyoid(int *o);
-</verb></tscreen>
-
-are provided to map between object identifiers and database entries.
-If you store a member of the <tt/oid_proto/ type in your association
-state information, it's a simple matter, at runtime, to generate the
-correct OID when you need it. For decoding, you can simply ignore the
-proto field, or if you're strict, you can verify that your peer is
-using the OID family from the correct protocol. The <tt/desc/ field is
-a short, human-readable name for the PDU, useful mainly for diagnostic
-output.
-
-<it>
-NOTE: The old function oid_getoidbyent still exists but is
-not thread safe. Use oid_ent_to_oid instead and pass an array of
-size OID_SIZE.
-</it>
-
-<it>
-NOTE: Plans are underway to merge the two protocols into a single
-definition, with one set of object identifiers. When this happens, the
-oid module will no longer be required to support protocol
-independence, but it should still be useful as a simple OID database.
-</it>
-
-<sect1>EXTERNAL Data
-
-<p>
-In order to achieve extensibility and adaptability to different
-application domains, the new version of the protocol defines many
-structures outside of the main ASN.1 specification, referencing them
-through ASN.1 EXTERNAL constructs. To simplify the construction and access
-to the externally referenced data, the <bf/ASN/ module defines a
-specialized version of the EXTERNAL construct, called <tt/Z_External/.
-It is defined thus:
-
-<tscreen><verb>
-typedef struct Z_External
-{
-    Odr_oid *direct_reference;
-    int *indirect_reference;
-    char *descriptor;
-    enum
-    {
-       /* Generic types */
-       Z_External_single = 0,
-       Z_External_octet,
-       Z_External_arbitrary,
-
-       /* Specific types */
-       Z_External_SUTRS,
-       Z_External_explainRecord,
-       Z_External_resourceReport1,
-       Z_External_resourceReport2
-
-       ...
-
-    } which;
-    union
-    {
-       /* Generic types */
-       Odr_any *single_ASN1_type;
-       Odr_oct *octet_aligned;
-       Odr_bitmask *arbitrary;
-
-       /* Specific types */
-       Z_SUTRS *sutrs;
-       Z_ExplainRecord *explainRecord;
-       Z_ResourceReport1 *resourceReport1;
-       Z_ResourceReport2 *resourceReport2;
-
-       ...
-
-    } u;
-} Z_External;
-</verb></tscreen>
-
-When decoding, the <bf/ASN/ module will attempt to determine which
-syntax describes the data by looking at the reference fields
-(currently only the direct-reference). For ASN.1 structured data, you
-need only consult the <tt/which/ field to determine the type of data.
-You can the access  the data directly through the union. When
-constructing data for encoding, you set the union pointer to point to
-the data, and set the <tt/which/ field accordingly. Remember also to
-set the direct (or indirect) reference to the correct OID for the data
-type. For non-ASN.1 data such as MARC records, use the
-<tt/octet_aligned/ arm of the union.
-
-Some servers return ASN.1 structured data values (eg. database
-records) as BER-encoded records placed in the <tt/octet-aligned/
-branch of the EXTERNAL CHOICE. The ASN-module will <it/not/
-automatically decode these records. To help you decode the records in
-the application, the function
-
-<tscreen><verb>
-Z_ext_typeent *z_ext_gettypebyref(oid_value ref);
-</verb></tscreen>
-
-Can be used to retrieve information about the known, external data
-types. The function return a pointer to a static area, or NULL, if no
-match for the given direct reference is found. The <tt/Z_ext_typeent/
-is defined as:
-
-<tscreen><verb>
-typedef struct Z_ext_typeent
-{
-    oid_value dref;    /* the direct-reference OID value. */
-    int what;          /* discriminator value for the external CHOICE */
-    Odr_fun fun;       /* decoder function */
-} Z_ext_typeent;
-</verb></tscreen>
-
-The <tt/what/ member contains the Z_External union discriminator value
-for the given type: For the SUTRS record syntax, the value would be
-<tt/Z_External_sutrs/. The <tt/fun/ member contains a pointer to the
-function which encodes/decodes the given type. Again, for the SUTRS
-record syntax, the value of <tt/fun/ would be <tt/z_SUTRS/ (a function
-pointer).
-
-If you receive an EXTERNAL which contains an octet-string value that
-you suspect of being an ASN.1-structured data value, you can use
-<tt/z_ext_gettypebyref/ to look for the provided direct-reference. If
-the return value is different from NULL, you can use the provided
-function to decode the BER string (see section <ref id="odr-use"
-name="Using ODR">).
-
-If you want to <it/send/ EXTERNALs containing ASN.1-structured values
-in the occtet-aligned branch of the CHOICE, this is possible too.
-However, on the encoding phase, it requires a somewhat involved
-juggling around of the various buffers involved.
-
-If you need to add new, externally defined data types, you must update
-the struct above, in the source file <tt/prt-ext.h/, as well as the
-encoder/decoder in the file <tt/prt-ext.c/. When changing the latter,
-remember to update both the <tt/arm/ arrary and the list <tt/type_table/,
-which drives the CHOICE biasing that is necessary to tell the
-different, structured types apart on decoding.
-
-<it>
-NOTE: Eventually, the EXTERNAL processing will most likely
-automatically insert the correct OIDs or indirect-refs. First,
-however, we need to determine how application-context management
-(specifically the presentation-context-list) should fit into the
-various modules.
-</it>
-
-<sect1>PDU Contents Table
-
-<p>
-We include, for reference, a listing of the fields of each top-level
-PDU, as well as their default settings.
-
-<verb>
-Z_InitRequest
--------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-protocolVersion              Odr_bitmask         Empty bitmask
-options                      Odr_bitmask         Empty bitmask
-preferredMessageSize         int                 30*1024
-maximumRecordSize            int                 30*1024
-idAuthentication             Z_IdAuthentication  NULL
-implementationId             char*               "YAZ (id=81)"
-implementationName           char*               "Index Data/YAZ"
-implementationVersion        char*               YAZ_VERSION
-userInformationField         Z_UserInformation   NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_InitResponse
---------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-protocolVersion              Odr_bitmask         Empty bitmask
-options                      Odr_bitmask         Empty bitmask
-preferredMessageSize         int                 30*1024
-maximumRecordSize            int                 30*1024
-result                       bool_t              TRUE
-implementationId             char*               "YAZ (id=81)"
-implementationName           char*               "Index Data/YAZ"
-implementationVersion        char*               YAZ_VERSION
-userInformationField         Z_UserInformat..    NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_SearchRequest
----------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-smallSetUpperBound           int                 0
-largeSetLowerBound           int                 1
-mediumSetPresentNumber       int                 0
-replaceIndicator             bool_t              TRUE
-resultSetName                char*               "default"
-num_databaseNames            int                 0
-databaseNames                char**              NULL
-smallSetElementSetNames      Z_ElementSetNames   NULL
-mediumSetElementSetNames     Z_ElementSetNames   NULL
-preferredRecordSyntax        Odr_oid             NULL
-query                        Z_Query             NULL
-additionalSearchInfo         Z_OtherInformation  NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_SearchResponse
-----------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-resultCount                  int                 0
-numberOfRecordsReturned      int                 0
-nextResultSetPosition        int                 0
-searchStatus                 bool_t              TRUE
-resultSetStatus              int                 NULL
-presentStatus                int                 NULL
-records                      Z_Records           NULL
-additionalSearchInfo         Z_OtherInformation  NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_PresentRequest
-----------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-resultSetId                  char*               "default"
-resultSetStartPoint          int                 1
-numberOfRecordsRequested     int                 10
-num_ranges                   int                 0
-additionalRanges             Z_Range             NULL
-recordComposition            Z_RecordComposition NULL
-preferredRecordSyntax        Odr_oid             NULL
-maxSegmentCount              int                 NULL
-maxRecordSize                int                 NULL
-maxSegmentSize               int                 NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_PresentResponse
------------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-numberOfRecordsReturned      int                 0
-nextResultSetPosition        int                 0
-presentStatus                int                 Z_PRES_SUCCESS
-records                      Z_Records           NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_DeleteResultSetRequest
-------------------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-deleteFunction               int                 Z_DeleteRequest_list
-num_ids                      int                 0
-resultSetList                char**              NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_DeleteResultSetResponse
--------------------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-deleteOperationStatus        int                 Z_DeleteStatus_success
-num_statuses                 int                 0
-deleteListStatuses           Z_ListStatus**      NULL
-numberNotDeleted             int                 NULL
-num_bulkStatuses             int                 0
-bulkStatuses                 Z_ListStatus        NULL
-deleteMessage                char*               NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_ScanRequest
--------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-num_databaseNames            int                 0
-databaseNames                char**              NULL
-attributeSet                 Odr_oid             NULL
-termListAndStartPoint        Z_AttributesPlus... NULL
-stepSize                     int                 NULL
-numberOfTermsRequested       int                 20
-preferredPositionInResponse  int                 NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_ScanResponse
---------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-stepSize                     int                 NULL
-scanStatus                   int                 Z_Scan_success
-numberOfEntriesReturned      int                 0
-positionOfTerm               int                 NULL
-entries                      Z_ListEntris        NULL
-attributeSet                 Odr_oid             NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_TriggerResourceControlRequest
--------------------------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-requestedAction              int                 Z_TriggerResourceCtrl_resou..
-prefResourceReportFormat     Odr_oid             NULL
-resultSetWanted              bool_t              NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_ResourceControlRequest
-------------------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-suspendedFlag                bool_t              NULL
-resourceReport               Z_External          NULL
-partialResultsAvailable      int                 NULL
-responseRequired             bool_t              FALSE
-triggeredRequestFlag         bool_t              NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_ResourceControlResponse
--------------------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-continueFlag                 bool_t              TRUE
-resultSetWanted              bool_t              NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_AccessControlRequest
-----------------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-which                        enum                Z_AccessRequest_simpleForm;
-u                            union               NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_AccessControlResponse
------------------------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-which                        enum                Z_AccessResponse_simpleForm
-u                            union               NULL
-diagnostic                   Z_DiagRec           NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_Segment
----------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-numberOfRecordsReturned      int                 value=0
-num_segmentRecords           int                 0
-segmentRecords               Z_NamePlusRecord    NULL
-otherInfo                    Z_OtherInformation  NULL
-
-Z_Close
--------
-Field                        Type                Default value
-
-referenceId                  Z_ReferenceId       NULL
-closeReason                  int                 Z_Close_finished
-diagnosticInformation        char*               NULL
-resourceReportFormat         Odr_oid             NULL
-resourceFormat               Z_External          NULL
-otherInfo                    Z_OtherInformation  NULL
-</verb>
-
-<sect>Supporting Tools
-
-<p>
-In support of the service API - primarily the ASN module, which
-provides the programmatic interface to the Z39.50 APDUs, YAZ contains
-a collection of tools that support the development of applications.
-
-<sect1>Query Syntax Parsers
-
-<p>
-Since the type-1 (RPN) query structure has no direct, useful string
-representation, every origin application needs to provide some form of
-mapping from a local query notation or representation to a
-<tt/Z_RPNQuery/ structure. Some programmers will prefer to construct
-the query manually, perhaps using <tt/odr_malloc()/ to simplify memory
-management. The YAZ distribution includes two separate,
-query-generating tools that may be of use to you.
-
-<sect2>Prefix Query Format<label id="PQF">
-
-<p>
-Since RPN or reverse polish notation is really just a fancy way of
-describing a suffix notation format (operator follows operands), it
-would seem that the confusion is total when we now introduce a prefix
-notation for RPN. The reason is one of simple laziness - it's somewhat
-simpler to interpret a prefix format, and this utility was designed
-for maximum simplicity, to provide a baseline representation for use
-in simple test applications and scripting environments (like Tcl). The
-demonstration client included with YAZ uses the PQF.
-
-The PQF is defined by the pquery module in the YAZ library. The
-<tt/pquery.h/ file provides the declaration of the functions
-
-<tscreen><verb>
-Z_RPNQuery *p_query_rpn (ODR o, oid_proto proto, const char *qbuf);
-
-Z_AttributesPlusTerm *p_query_scan (ODR o, oid_proto proto,
-      Odr_oid **attributeSetP, const char *qbuf);
-
-int p_query_attset (const char *arg);
-</verb></tscreen>
-
-The function <tt/p_query_rpn()/ takes as arguments an <bf/ODR/ stream
-(see section <ref id="odr" name="The ODR Module">) to provide a memory
-source (the structure created is released on the next call to
-<tt/odr_reset()/ on the stream/), a protocol identifier (one of the
-constants <tt/PROTO_Z3950/ and <tt/PROTO_SR/), an attribute set
-reference, and finally a null-terminated string holding the query
-string.
-
-If the parse went well, <tt/p_query_rpn()/ returns a pointer to a
-<tt/Z_RPNQuery/ structure which can be placed directly into a
-<tt/Z_SearchRequest/.
-
-The <tt/p_query_attset/ specifies which attribute set to use if
-the query doesn't specify one by the <tt/@attrset/ operator. The
-<tt/p_query_attset/ returns 0 if the argument is a valid attribute
-set specifier; otherwise the function returns -1.
-
-The grammar of the PQF is as follows:
-
-<tscreen><verb>
-Query ::= &lsqb; AttSet &rsqb; QueryStruct.
-
-AttSet ::= string.
-
-QueryStruct ::= { Attribute } Simple | Complex.
-
-Attribute ::= '@attr' AttributeType '=' AttributeValue.
-
-AttributeType ::= integer.
-
-AttributeValue ::= integer.
-
-Complex ::= Operator QueryStruct QueryStruct.
-
-Operator ::= '@and' | '@or' | '@not' | '@prox' Proximity.
-
-Simple ::= ResultSet | Term.
-
-ResultSet ::= '@set' string.
-
-Term ::= string | '"' string '"'.
-
-Proximity ::= Exclusion Distance Ordered Relation WhichCode UnitCode.
-
-Exclusion ::= '1' | '0' | 'void'.
-
-Distance ::= integer.
-
-Ordered ::= '1' | '0'.
-
-Relation ::= integer.
-
-WhichCode ::= 'known' | 'private' | integer.
-
-UnitCode ::= integer.
-</verb></tscreen>
-
-You will note that the syntax above is a fairly faithful
-representation of RPN, except for the <tt/Attibute/, which has been
-moved a step away from the term, allowing you to associate one or more
-attributes with an entire query structure. The parser will
-automatically apply the given attributes to each term as required.
-
-The following are all examples of valid queries in the PQF.
-
-<tscreen><verb>
-dylan
-
-"bob dylan"
-
-@or "dylan" "zimmerman"
-
-@set Result-1
-
-@or @and bob dylan @set Result-1
-
-@attr 4=1 @and @attr 1=1 "bob dylan" @attr 1=4 "slow train coming"
-
-@attr 4=1 @attr 1=4 "self portrait"
-
-@prox 0 3 1 2 k 2 dylan zimmerman
-</verb></tscreen>
-
-<sect2>Common Command Language<label id="CCL">
-
-<p>
-Not all users enjoy typing in prefix query structures and numerical
-attribute values, even in a minimalistic test client. In the library
-world, the more intuitive Common Command Language (or ISO 8777) has
-enjoyed some popularity - especially before the widespread
-availability of graphical interfaces. It is still useful in
-applications where you for some reason or other need to provide a
-symbolic language for expressing boolean query structures.
-
-The EUROPAGATE research project working under the Libraries programme
-of the European Commission's DG XIII has, amongst other useful tools,
-implemented a general-purpose CCL parser which produces an output
-structure that can be trivially converted to the internal RPN
-representation of YAZ (The <tt/Z_RPNQuery/ structure). Since the CCL
-utility - along with the rest of the software produced by EUROPAGATE -
-is made freely available on a liberal license, it is included as a
-supplement to YAZ.
-
-<sect3>CCL Syntax
-<p>
-The CCL parser obeys the following grammar for the FIND argument.
-The syntax is annotated by in the lines prefixed by <tt/--/.
-
-<tscreen><verb>
-CCL-Find ::= CCL-Find Op Elements
-           | Elements.
-
-Op ::= "and" | "or" | "not"
--- The above means that Elements are separated by boolean operators.
-
-Elements ::= '(' CCL-Find ')'
-           | Set
-           | Terms
-           | Qualifiers Relation Terms
-           | Qualifiers Relation '(' CCL-Find ')'
-           | Qualifiers '=' string '-' string
--- Elements is either a recursive definition, a result set reference, a
--- list of terms, qualifiers followed by terms, qualifiers followed
--- by a recursive definition or qualifiers in a range (lower - upper).
-
-Set ::= 'set' = string
--- Reference to a result set
-
-Terms ::= Terms Prox Term
-        | Term
--- Proximity of terms.
-
-Term ::= Term string
-       | string
--- This basically means that a term may include a blank
-
-Qualifiers ::= Qualifiers ',' string
-             | string
--- Qualifiers is a list of strings separated by comma
-
-Relation ::= '=' | '>=' | '<=' | '<>' | '>' | '<'
--- Relational operators. This really doesn't follow the ISO8777
--- standard.
-
-Prox ::= '%' | '!'
--- Proximity operator
-
-</verb></tscreen>
-
-The following queries are all valid:
-
-<tscreen><verb>
-dylan
-
-"bob dylan"
-
-dylan or zimmerman
-
-set=1
-
-(dylan and bob) or set=1
-
-</verb></tscreen>
-Assuming that the qualifiers <tt/ti/, <tt/au/ and <tt/date/
-are defined we may use:
-<tscreen><verb>
-ti=self portrait
-
-au=(bob dylan and slow train coming)
-
-date>1980 and (ti=((self portrait)))
-</verb></tscreen>
-
-<sect3>CCL Qualifiers
-<p>
-
-Qualifiers are used to direct the search to a particular searchable
-index, such as title (ti) and author indexes (au). The CCL standard
-itself doesn't specify a particular set of qualifiers, but it does
-suggest a few short-hand notations. You can customize the CCL parser
-to support a particular set of qualifiers to relect the current target
-profile. Traditionally, a qualifier would map to a particular
-use-attribute within the BIB-1 attribute set. However, you could also
-define qualifiers that would set, for example, the
-structure-attribute.
-
-Consider a scenario where the target support ranked searches in the
-title-index. In this case, the user could specify
-<tscreen><verb>
-ti,ranked=knuth computer
-</verb></tscreen>
-and the <tt/ranked/ would map to structure=free-form-text
-(4=105) and the <tt/ti/ would map to title (1=4).
-
-A "profile" with a set predefined CCL qualifiers can be read from a
-file. The YAZ client reads its CCL qualifiers from a file named
-<tt/default.bib/. Each line in the file has the form:
-
-<it/qualifier-name/    <it/type/=<it/val/ <it/type/=<it/val/ ...
-
-where <it/qualifier-name/ is the name of the qualifier to be used
-(eg. <tt/ti/), <it/type/ is a BIB-1 category type and <it/val/ is the
-corresponding BIB-1 attribute value. The <it/type/ can be either
-numeric or it may be either <tt/u/ (use), <tt/r/ (relation), <tt/p/
-(position), <tt/s/ (structure), <tt/t/ (truncation) or <tt/c/
-(completeness). The <it/qualifier-name/ <tt/term/ has a special
-meaning. The types and values for this definition is used when <it/no/
-qualifier is present.
-
-Consider the following definition:
-<tscreen><verb>
-ti       u=4 s=1
-au       u=1 s=1
-term     s=105
-</verb></tscreen>
-Two qualifiers are defined, <tt/ti/ and <tt/au/. They both set the
-structure-attribute to phrase (1). <tt/ti/ sets the use-attribute to
-4. <tt/au/ sets the use-attribute to 1. When no qualifiers are used
-in the query the structure-attribute is set to free-form-text (105).
-
-<sect3>CCL API
-<p>
-
-All public definitions can be found in the header file <tt/ccl.h/.
-A profile identifier is of type <tt/CCL_bibset/. A profile must be
-created with the call to the function <tt/ccl_qual_mk/ which returns
-a profile handle of type <tt/CCL_bibset/.
-
-To read a file containing qualifier definitions the function
-<tt/ccl_qual_file/ may be convenient. This function takes an already
-opened <tt/FILE/ handle pointer as argument along with a
-<tt/CCL_bibset/ handle.
-
-To parse a simple string with a FIND query use the function
-<tscreen><verb>
-struct ccl_rpn_node *ccl_find_str (CCL_bibset bibset, const char *str,
-                                   int *error, int *pos);
-</verb></tscreen>
-which takes the CCL profile (<tt/bibset/) and query (<tt/str/) as
-input. Upon successful completion the RPN tree is returned. If an
-error eccur, such as a syntax error, the integer pointed to by
-<tt/error/ holds the error code and <tt/pos/ holds the offset inside
-query string in which the parsing failed.
-
-An english representation of the error may be obtained by calling
-the <tt/ccl_err_msg/ function. The error codes are listed in
-<tt/ccl.h/.
-
-To convert the CCL RPN tree (type <tt/struct ccl_rpn_node */) to the
-Z_RPNQuery of YAZ the function <tt/ccl_rpn_query/ must be used. This
-function which is part of YAZ is implemented in <tt/yaz-ccl.c/.
-After calling this function the CCL RPN tree is probably no longer
-needed. The <tt/ccl_rpn_delete/ destroys the CCL RPN tree.
-
-A CCL profile may be destroyed by calling the <tt/ccl_qual_rm/
-function.
-
-The token names for the CCL operators may be changed by setting the
-globals (all type <tt/char */) <tt/ccl_token_and/, <tt/ccl_token_or/,
-<tt/ccl_token_not/ and <tt/ccl_token_set/.
-An operator may have aliases, i.e. there may be more than one name for
-the operator. To do this, separate each alias with a space character.
-
-<sect1>Object Identifiers
-
-<p>
-The basic YAZ representation of an OID is an array of integers,
-terminated with the value -1. The <bf/ODR/ module provides two
-utility-functions to create and copy this type of data elements:
-
-<tscreen><verb>
-Odr_oid *odr_getoidbystr(ODR o, char *str);
-</verb></tscreen>
-
-Creates an OID based on a string-based representation using dots (.)
-to separate elements in the OID.
-
-<tscreen><verb>
-Odr_oid *odr_oiddup(ODR odr, Odr_oid *o);
-</verb></tscreen>
-
-Creates a copy of the OID referenced by the <it/o/ parameter. Both
-functions take an <bf/ODR/ stream as parameter. This stream is used to
-allocate memory for the data elements, which is released on a
-subsequent call to <tt/odr_reset()/ on that stream.
-
-The <bf/OID/ module provides a higher-level representation of the
-family of object identifers which describe the Z39.50 protocol and its
-related objects. The definition of the module interface is given in
-the <tt/oid.h/ file.
-
-The interface is mainly based on the <tt/oident/ structure. The
-definition of this structure looks like this:
-
-<tscreen><verb>
-typedef struct oident
-{
-    oid_proto proto;
-    oid_class oclass;
-    oid_value value;
-    int oidsuffix[OID_SIZE];
-    char *desc;
-} oident;
-</verb></tscreen>
-
-The <it/proto/ field takes one of the values
-
-<tscreen><verb>
-PROTO_Z3950
-PROTO_SR
-</verb></tscreen>
-
-If you don't care about talking to SR-based implementations (few
-exist, and they may become fewer still if and when the ISO SR and ANSI
-Z39.50 documents are merged into a single standard), you can ignore
-this field on incoming packages, and always set it to PROTO_Z3950
-for outgoing packages.
-
-The <it/oclass/ field takes one of the values
-
-<tscreen><verb>
-CLASS_APPCTX
-CLASS_ABSYN
-CLASS_ATTSET
-CLASS_TRANSYN
-CLASS_DIAGSET
-CLASS_RECSYN
-CLASS_RESFORM
-CLASS_ACCFORM
-CLASS_EXTSERV
-CLASS_USERINFO
-CLASS_ELEMSPEC
-CLASS_VARSET
-CLASS_SCHEMA
-CLASS_TAGSET
-CLASS_GENERAL
-</verb></tscreen>
-
-corresponding to the OID classes defined by the Z39.50 standard.
-
-Finally, the <it/value/ field takes one of the values
-
-<tscreen><verb>
-VAL_APDU
-VAL_BER
-VAL_BASIC_CTX
-VAL_BIB1
-VAL_EXP1
-VAL_EXT1
-VAL_CCL1
-VAL_GILS
-VAL_WAIS
-VAL_STAS
-VAL_DIAG1
-VAL_ISO2709
-VAL_UNIMARC
-VAL_INTERMARC
-VAL_CCF
-VAL_USMARC
-VAL_UKMARC
-VAL_NORMARC
-VAL_LIBRISMARC
-VAL_DANMARC
-VAL_FINMARC
-VAL_MAB
-VAL_CANMARC
-VAL_SBN
-VAL_PICAMARC
-VAL_AUSMARC
-VAL_IBERMARC
-VAL_EXPLAIN
-VAL_SUTRS
-VAL_OPAC
-VAL_SUMMARY
-VAL_GRS0
-VAL_GRS1
-VAL_EXTENDED
-VAL_RESOURCE1
-VAL_RESOURCE2
-VAL_PROMPT1
-VAL_DES1
-VAL_KRB1
-VAL_PRESSET
-VAL_PQUERY
-VAL_PCQUERY
-VAL_ITEMORDER
-VAL_DBUPDATE
-VAL_EXPORTSPEC
-VAL_EXPORTINV
-VAL_NONE
-VAL_SETM
-VAL_SETG
-VAL_VAR1
-VAL_ESPEC1
-</verb></tscreen>
-
-again, corresponding to the specific OIDs defined by the standard.
-
-The <it/desc/ field contains a brief, mnemonic name for the OID in
-question.
-
-The function
-
-<tscreen><verb>
-struct oident *oid_getentbyoid(int *o);
-</verb></tscreen>
-
-takes as argument an OID, and returns a pointer to a static area
-containing an <tt/oident/ structure. You typically use this function
-when you receive a PDU containing an OID, and you wish to branch out
-depending on the specific OID value.
-
-The function
-
-<tscreen><verb>
-int *oid_ent_to_oid(struct oident *ent, int *dst);
-</verb></tscreen>
-
-Takes as argument an <tt/oident/ structure - in which the <it/proto/,
-<it/oclass/, and <it/value/ fields are assumed to be set correctly -
-and returns a pointer to a the buffer as given by <it/dst/
-containing the base
-representation of the corresponding OID. The function returns
-NULL and the array dst is unchanged if a mapping couldn't place.
-The array <it/dst/ should be at least of size <tt>OID_SIZE</tt>.
-
-The <tt/oid_ent_to_oid()/ function can be used whenever you need to
-prepare a PDU containing one or more OIDs. The separation of the
-<it/protocol/ element from the remainer of the OID-description makes
-it simple to write applications that can communicate with either
-Z39.50 or OSI SR-based applications.
-
-The function
-
-<tscreen><verb>
-oid_value oid_getvalbyname(const char *name);
-</verb></tscreen>
-
-takes as argument a mnemonic OID name, and returns the <it/value/
-field of the first entry in the database that contains the given name
-in its <it/desc/ field.
-
-Finally, the module provides the following utility functions, whose
-meaning should be obvious:
-
-<tscreen><verb>
-void oid_oidcpy(int *t, int *s);
-void oid_oidcat(int *t, int *s);
-int oid_oidcmp(int *o1, int *o2);
-int oid_oidlen(int *o);
-</verb></tscreen>
-
-<it>
-NOTE: The <bf/OID/ module has been criticized - and perhaps rightly so
-- for needlessly abstracting the
-representation of OIDs. Other toolkits use a simple
-string-representation of OIDs with good results. In practice, we have
-found the interface comfortable and quick to work with, and it is a
-simple matter (for what it's worth) to create applications compatible
-with both ISO SR and Z39.50. Finally, the use of the <tt/oident/
-database is by no means mandatory. You can easily create your
-own system for representing OIDs, as long as it is compatible with the
-low-level integer-array representation of the ODR module.
-</it>
-
-<sect1>Nibble Memory
-
-<p>
-Sometimes when you need to allocate and construct a large,
-interconnected complex of structures, it can be a bit of a pain to
-release the associated memory again. For the structures describing the
-Z39.50 PDUs and related structures, it is convenient to use the
-memory-management system of the <bf/ODR/ subsystem (see
-<ref id="odr-use" name="Using ODR">). However, in some circumstances
-where you might otherwise benefit from using a simple nibble memory
-management system, it may be impractical to use <tt/odr_malloc()/ and
-<bf/odr_reset()/. For this purpose, the memory manager which also
-supports the <bf/ODR/ streams is made available in the <bf/NMEM/
-module. The external interface to this module is given in the
-<tt/nmem.h/ file.
-
-The following prototypes are given:
-
-<tscreen><verb>
-NMEM nmem_create(void);
-void nmem_destroy(NMEM n);
-void *nmem_malloc(NMEM n, int size);
-void nmem_reset(NMEM n);
-int nmem_total(NMEM n);
-void nmem_init(void);
-</verb></tscreen>
-
-The <tt/nmem_create()/ function returns a pointer to a memory control
-handle, which can be released again by <tt/nmem_destroy()/ when no
-longer needed. The function <tt/nmem_malloc()/ allocates a block of
-memory of the requested size. A call to <tt/nmem_reset()/ or
-<tt/nmem_destroy()/ will release all memory allocated on the handle
-since it was created (or since the last call to
-<tt/nmem_reset()/. The function <tt/nmem_total()/ returns the number
-of bytes currently allocated on the handle.
-
-Note that the nibble memory pool is shared amonst threads. Posix
-mutex'es and WIN32 Critical sections are introduced to keep the
-module thread safe. On WIN32 function <tt/nmem_init()/ initialises
-the Critical Section handle and should be called once before any
-other nmem function is used.
-
-<sect>The ODR Module<label id="odr">
-
-<sect1>Introduction
-
-<p>
-<bf/ODR/ is the BER-encoding/decoding subsystem of <bf/YAZ/. Care as been taken
-to isolate <bf/ODR/ from the rest of the package - specifically from the
-transport interface. <bf/ODR/ may be used in any context where basic
-ASN.1/BER representations are used.
-
-If you are only interested in writing a Z39.50 implementation based on
-the PDUs that are already provided with <bf/YAZ/, you only need to concern
-yourself with the section on managing ODR streams (section
-<ref id="odr-use" name="Using ODR">). Only if you need to
-implement ASN.1 beyond that which has been provided, should you
-worry about the second half of the documentation
-(section <ref id="odr-prog" name="Programming with ODR">). If you use
-one of the higher-level interfaces, you can skip this section entirely.
-
-This is important, so we'll repeat it for emphasis: <it>You do not
-need to read section <ref id="odr-prog" name="Programming with ODR"> to
-implement Z39.50 with <bf/YAZ/.</it>
-
-If you need a part of the protocol that isn't already in <bf/YAZ/, you
-should
-contact the authors before going to work on it yourself: We
-might already be working on it. Conversely, if you implement a useful
-part of the protocol before us, we'd be happy to include it in a
-future release.
-
-<sect1>Using ODR<label id="odr-use">
-
-<p>
-<sect2>ODR Streams
-
-<p>
-Conceptually, the ODR stream is the source of encoded data in the
-decoding mode; when encoding, it is the receptacle for the encoded
-data. Before you can use an ODR stream it must be allocated. This is
-done with the function
-
-<tscreen><verb>
-ODR odr_createmem(int direction);
-</verb></tscreen>
-
-The <tt/odr_createmem()/ function takes as argument one of three manifest
-constants: <tt/ODR_ENCODE/, <tt/ODR_DECODE/, or <tt/ODR_PRINT/. An
-ODR stream can be
-in only one mode - it is not possible to change its mode once it's
-selected. Typically, your program will allocate at least two ODR
-streams - one for decoding, and one for encoding.
-
-When you're done with the stream, you can use
-
-<tscreen><verb>
-void odr_destroy(ODR o);
-</verb></tscreen>
-
-to release the resources allocated for the stream.
-
-<sect2>Memory Management<label id="memory">
-
-<p>
-Two forms of memory management take place in the ODR system. The first
-one, which has to do with allocating little bits of memory (sometimes
-quite large bits of memory, actually) when a protocol package is
-decoded, and turned into a complex of interlinked structures. This
-section deals with this system, and how you can use it for your own
-purposes. The next section deals with the memory management which is
-required when encoding data - to make sure that a large enough buffer is
-available to hold the fully encoded PDU.
-
-The <bf/ODR/ module has its own memory management system, which is
-used whenever memory is required. Specifically, it is used to allocate
-space for data when decoding incoming PDUs. You can use the memory
-system for your own purposes, by using the function
-
-<tscreen><verb>
-void *odr_malloc(ODR o, int size);
-</verb></tscreen>
-
-You can't use the normal <tt/free/(2) routine to free memory allocated
-by this function, and <bf/ODR/ doesn't provide a parallel function. Instead,
-you can call
-
-<tscreen><verb>
-void odr_reset(ODR o, int size);
-</verb></tscreen>
-
-when you are done with the
-memory: Everything allocated since the last call to <tt/odr_reset()/ is
-released. The <tt/odr_reset()/ call is also required to clear up an
-error condition on a stream.
-
-The function
-
-<tscreen><verb>
-int odr_total(ODR o);
-</verb></tscreen>
-
-returns the number of bytes allocated on the stream since the last call to
-<tt/odr_reset()/.
-
-The memory subsystem of <bf/ODR/ is fairly efficient at allocating and
-releasing little bits of memory. Rather than managing the individual,
-small bits of space, the system maintains a freelist of larger chunks
-of memory, which are handed out in small bits. This scheme is
-generally known as a <it/nibble memory/ system. It is very useful for
-maintaing short-lived constructions such as protocol PDUs.
-
-If you want to retain a bit of memory beyond the next call to
-<tt/odr_reset()/, you can use the function
-
-<tscreen><verb>
-ODR_MEM odr_extract_mem(ODR o);
-</verb></tscreen>
-
-This function will give you control of the memory recently allocated
-on the ODR stream. The memory will live (past calls to <tt/odr_reset()/),
-until you call the function
-
-<tscreen><verb>
-void odr_release_mem(ODR_MEM p);
-</verb></tscreen>
-
-The opaque <tt/ODR_MEM/ handle has no other purpose than referencing
-the memory block for you until you want to release it.
-
-You can use <tt/odr_extract_mem()/ repeatedly between allocating data,
-to retain individual control of separate chunks of data.
-
-<sect2>Encoding and Decoding Data
-
-<p>
-When encoding data, the ODR stream will write the encoded octet string
-in an internal buffer. To retrieve the data, use the function
-
-<tscreen><verb>
-char *odr_getbuf(ODR o, int *len, int *size);
-</verb></tscreen>
-
-The integer pointed to by len is set to the length of the encoded
-data, and a pointer to that data is returned. *<tt/size/ is set to the size
-of the buffer (unless <tt/size/ is null, signalling that you are
-not interested in the size). The next call to a primitive function
-using the same ODR stream will overwrite the data, unless a different
-buffer has been supplied using the call
-
-<tscreen><verb>
-void odr_setbuf(ODR o, char *buf, int len, int can_grow);
-</verb></tscreen>
-
-which sets the encoding (or decoding) buffer used by <tt/o/ to
-<tt/buf/,
-using the length <tt/len/. Before a call to an encoding function,
-you can use <tt/odr_setbuf()/ to provide the stream with an encoding buffer
-of sufficient size (length). The <tt/can_grow/ parameter tells the encoding
-ODR stream whether it is allowed to use <tt/realloc/(2) to increase the size
-of the buffer when necessary. The default condition of a new encoding
-stream is equivalent to the results of calling
-
-<tscreen><verb>
-odr_setbuf(stream, 0, 0, 1);
-</verb></tscreen>
-
-In this case, the stream will allocate and reallocate memory as
-necessary. The stream reallocates memory by repeatedly doubling the
-size of the buffer - the result is that the buffer will typically
-reach its maximum, working size with only a small number of reallocation
-operations. The memory is freed by the stream when the latter is destroyed,
-unless it was assigned by the user with the <tt/can_grow/
-parameter set to zero (in this case, you are expected to retain
-control of the memory yourself).
-
-To assume full control of an encoded buffer, you must first call
-<tt/odr_getbuf()/ to fetch the buffer and its length. Next, you should
-call <tt/odr_setbuf()/ to provide a different buffer (or a null
-pointer) to the stream. In the simplest case, you will reuse the same
-buffer over and over again, and you will just need to call
-<tt/odr_getbuf()/ after each encoding operation to get the length and
-address of the buffer. Note that the stream may reallocate the buffer
-during an encoding operation, so it is necessary to retrieve the
-correct address after each encoding operation.
-
-It is important to realise that the ODR stream will not release this
-memory when you call <tt/odr_reset()/: It will merely update its
-internal pointers to prepare for the encoding of a new data value.
-When the stream is released by the <tt/odr_destroy()/ function, the
-memory given to it by odr_setbuf will be released <it/only/ if the
-<tt/can_grow/ parameter to <tt/odr_setbuf()/ was nonzero. The
-<tt/can_grow/ parameter, in other words, is a way of signalling who
-is to own the buffer, you or the ODR stream. If you never call
-<tt/odr_setbuf()/ on your encoding stream, which is typically the
-case, the buffer allocated by the stream will belong to the stream by
-default.
-
-When you wish to decode data, you should first call <tt/odr_setbuf()/, to
-tell the decoding stream where to find the encoded data, and how long
-the buffer is (the <tt/can_grow/ parameter is ignored by a decoding
-stream). After this, you can call the function corresponding to the
-data you wish to decode (eg, <tt/odr_integer()/ odr <tt/z_APDU()/).
-
-Examples of encoding/decoding functions:
-
-<tscreen><verb>
-int odr_integer(ODR o, int **p, int optional, const char *name);
-
-int z_APDU(ODR o, Z_APDU **p, int optional, const char *name);
-</verb></tscreen>
-
-If the data is absent (or
-doesn't match the tag corresponding to the type), the return value
-will be either 0 or 1 depending on the <tt/optional/ flag. If
-<tt/optional/
-is 0 and the data is absent, an error flag will be raised in the
-stream, and you'll need to call <tt/odr_reset()/ before you can use the
-stream again. If <tt/optional/ is nonzero, the pointer <it/pointed to/ by
-<tt/p/ will be set to the null value, and the function will return 1.
-The <tt/name/ argument is used to pretty-print the tag in question.
-It may be set to <tt/NULL/ if pretty-printing is not desired.
-
-If the data value is found where it's expected, the pointer
-<it/pointed to/ by the <tt/p/ argument will be set to point to the
-decoded type. The
-space for the type will be allocated and owned by the ODR stream, and
-it will live until you call <tt/odr_reset()/ on the stream. You cannot use
-<tt/free/(2) to release the memory. You can decode several data elements
-(by repeated calls to <tt/odr_setbuf()/ and your decoding function), and
-new memory will be allocated each time. When you do call
-<tt/odr_reset()/,
-everything decoded since the last call to <tt/odr_reset()/ will be
-released.
-
-The use of the double indirection can be a little confusing at first
-(its purpose will become clear later on, hopefully),
-so an example is in order. We'll encode an integer value, and
-immediately decode it again using a different stream. A useless, but
-informative operation.
-
-<tscreen><verb>
-void do_nothing_useful(int value)
-{
-    ODR encode, decode;
-    int *valp, *resvalp;
-    char *bufferp;
-    int len;
-
-    /* allocate streams */
-    if (!(encode = odr_createmem(ODR_ENCODE)))
-       return;
-    if (!(decode = odr_createmem(ODR_DECODE)))
-       return;
-
-    valp = &ero;value;
-    if (odr_integer(encode, &ero;valp, 0, 0) == 0)
-    {
-       printf("encoding went bad\n");
-       return;
-    }
-    bufferp = odr_getbuf(encode, &ero;len);
-    printf("length of encoded data is &percnt;d\n", len);
-
-    /* now let's decode the thing again */
-    odr_setbuf(decode, bufferp, len);
-    if (odr_integer(decode, &ero;resvalp, 0, 0) == 0)
-    {
-       printf("decoding went bad\n");
-       return;
-    }
-    printf("the value is &percnt;d\n", *resvalp);
-
-    /* clean up */
-    odr_destroy(encode);
-    odr_destroy(decode);
-}
-</verb></tscreen>
-
-This looks like a lot of work, offhand. In practice, the ODR streams
-will typically be allocated once, in the beginning of your program (or at the
-beginning of a new network session), and the encoding and decoding
-will only take place in a few, isolated places in your program, so the
-overhead is quite manageable.
-
-<sect2>Diagnostics
-
-<p>
-The encoding/decoding functions all return 0 when an error occurs.
-Until you call <tt/odr_reset()/, you cannot use the stream again, and
-any function called will immediately return 0.
-
-To provide information to the programmer or administrator, the
-function
-
-<tscreen><verb>
-void odr_perror(ODR o, char *message);
-</verb></tscreen>
-
-is provided, which prints the <tt/message/ argument to <tt/stderr/
-along with an error message from the stream.
-
-You can also use the function
-
-<tscreen><verb>
-int odr_geterror(ODR o);
-</verb></tscreen>
-
-to get the current error number from the screen. The number will be
-one of these constants:
-
-<descrip>
-<tag/OMEMORY/Memory allocation failed.
-<tag/OSYSERR/A system- or library call has failed. The standard
-diagnostic variable <tt/errno/
-should be examined to determine the actual error.
-<tag/OSPACE/No more space for encoding. This will only occur when the user has
-explicitly provided a buffer for an encoding stream without allowing
-the system to allocate more space.
-<tag/OREQUIRED/This is a common protocol error; A required data element was
-missing during
-encoding or decoding.
-<tag/OUNEXPECTED/An unexpected data element was found during decoding.
-<tag/OOTHER/Other error. This is typically an indication of misuse of
-the <bf/ODR/ system by the programmer, and also that the diagnostic
-system isn't as good as it should be, yet.
-</descrip>
-
-The character string array
-
-<tscreen><verb>
-char *odr_errlist&lsqb;&rsqb;
-</verb></tscreen>
-
-can be indexed by the error code to obtain a human-readable
-representation of the problem.
-
-<sect2>Summary and Synopsis
-
-<p>
-<tscreen><verb>
-#include <odr.h>
-
-ODR odr_createmem(int direction);
-
-void odr_destroy(ODR o);
-
-void odr_reset(ODR o);
-
-char *odr_getbuf(ODR o, int *len);
-
-void odr_setbuf(ODR o, char *buf, int len);
-
-void *odr_malloc(ODR o, int size);
-
-ODR_MEM odr_extract_mem(ODR o);
-
-void odr_release_mem(ODR_MEM r);
-
-int odr_geterror(ODR o);
-
-void odr_perror(char *message);
-
-extern char *odr_errlist[];
-</verb></tscreen>
-
-<sect1>Programming with ODR<label id="odr-prog">
-
-<p>
-The API of <bf/ODR/ is designed to reflect the structure of ASN.1, rather
-than BER itself. Future releases may be able to represent data in
-other external forms.
-
-The interface is based loosely on that of the Sun Microsystems XDR routines.
-Specifically, each function which corresponds to an ASN.1 primitive
-type has a dual function. Depending on the settings of the ODR
-stream which is supplied as a parameter, the function may be used
-either to encode or decode data. The functions that can be built
-using these primitive functions, to represent more complex datatypes, share
-this quality. The result is that you only have to enter the definition
-for a type once - and you have the functionality of encoding, decoding
-(and pretty-printing) all in one unit. The resulting C source code is
-quite compact, and is a pretty straightforward representation of the
-source ASN.1 specification. Although no ASN.1 compiler is supplied
-with <bf/ODR/ at this time, it shouldn't be too difficult to write one, or
-perhaps even to adapt an existing compiler to output <bf/ODR/ routines
-(not surprisingly, writing encoders/decoders using <bf/ODR/ turns out
-to be boring work).
-
-In many cases, the model of the XDR functions works quite well in this
-role. In
-others, it is less elegant. Most of the hassle comes from the optional
-SEQUENCE memebers which don't exist in XDR.
-
-<sect2>The Primitive ASN.1 Types
-
-<p>
-ASN.1 defines a number of primitive types (many of which correspond
-roughly to
-primitive types in structured programming languages, such as C).
-
-<sect3>INTEGER
-
-<p>
-The <bf/ODR/ function for encoding or decoding (or printing) the ASN.1
-INTEGER type looks like this:
-
-<tscreen><verb>
-int odr_integer(ODR o, int **p, int optional, const char *name);
-</verb></tscreen>
-
-(we don't allow values that can't be contained in a C integer.)
-
-This form is typical of the primitive <bf/ODR/ functions. They are named
-after the type of data that they encode or decode. They take an
-ODR
-stream, an indirect reference to the type in question, and an
-<tt/optional/ flag (corresponding to the OPTIONAL keyword of ASN.1) as
-parameters. They all return an integer value of either one or zero.
-When you use the primitive functions to construct encoders for complex
-types of your own, you should follow this model as well. This
-ensures that your new types can be reused as elements in yet more
-complex types.
-
-The <tt/o/ parameter should obviously refer to a properly
-initialized ODR
-stream of the right type (encoding/decoding/printing) for the
-operation that you wish to perform.
-
-When encoding or printing, the function first looks at *<tt/p/. If
-*<tt/p/ (the
-pointer pointed to by <tt/p/) is a null pointer, this is taken to mean that
-the data element is absent. If the <tt/optional/ parameter is nonzero,
-the function will return one (signifying success) without any further
-processing. If the <tt/optional/ is zero, an internal error flag is
-set in the ODR stream, and the function will return 0. No further
-operations can be carried out on the stream without a call to
-the function <tt/odr_reset()/.
-
-If *<tt/p/ is not a null pointer, it is expected to point to an instance of
-the data type. The data will be subjected to the encoding rules, and
-the result will be placed in the buffer held by the ODR stream.
-
-The other ASN.1 primitives have similar functions that operate in
-similar manners:
-
-<sect3>BOOLEAN
-
-<p>
-<tscreen><verb>
-int odr_bool(ODR o, bool_t **p, int optional, const char *name);
-</verb></tscreen>
-
-<sect3>REAL
-
-<p>
-Not defined.
-
-<sect3>NULL
-
-<p>
-<tscreen><verb>
-int odr_null(ODR o, bool_t **p, int optional, const char *name);
-</verb></tscreen>
-
-In this case, the value of **p is not important. If *p is different
-from the null pointer, the null value is present, otherwise it's
-absent.
-
-<sect3>OCTET STRING
-
-<p>
-<tscreen><verb>
-typedef struct odr_oct
-{
-    unsigned char *buf;
-    int len;
-    int size;
-} Odr_oct;
-
-int odr_octetstring(ODR o, Odr_oct **p, int optional, const char *name);
-</verb></tscreen>
-
-The <tt/buf/ field should point to the character array that holds the
-octetstring. The <tt/len/ field holds the actual length, while the
-<tt/size/
-field gives the size of the allocated array (not of interest to you,
-in most cases). The character array need not be null terminated.
-
-To make things a little easier, an alternative is given for string
-types that are not expected to contain embedded NULL characters (eg.
-VisibleString):
-
-<tscreen><verb>
-int odr_cstring(ODR o, char **p, int optional, const char *name);
-</verb></tscreen>
-
-Which encoded or decodes between OCTETSTRING representations and
-null-terminates C strings.
-
-Functions are provided for the derived string types, eg:
-
-<tscreen><verb>
-int odr_visiblestring(ODR o, char **p, int optional, const char *name);
-</verb></tscreen>
-
-<sect3>BIT STRING
-
-<p>
-<tscreen><verb>
-int odr_bitstring(ODR o, Odr_bitmask **p, int optional, const char *name);
-</verb></tscreen>
-
-The opaque type <tt/Odr_bitmask/ is only suitable for holding relatively brief bit
-strings, eg. for options fields, etc. The constant
-<tt/ODR_BITMASK_SIZE/
-multiplied by 8 gives the maximum possible number of bits.
-
-A set of macros are provided for manipulating the
-<tt/Odr_bitmask/
-type:
-
-<tscreen><verb>
-void ODR_MASK_ZERO(Odr_bitmask *b);
-
-void ODR_MASK_SET(Odr_bitmask *b, int bitno);
-
-void ODR_MASK_CLEAR(Odr_bitmask *b, int bitno);
-
-int ODR_MASK_GET(Odr_bitmask *b, int bitno);
-</verb></tscreen>
-
-The functions are modelled after the manipulation functions that
-accompany the <tt/fd_set/ type used by the <tt/select/(2) call.
-<tt/ODR_MASK_ZERO/ should always be called first on a new bitmask, to
-initialize the bits to zero.
-
-<sect3>OBJECT IDENTIFIER
-
-<p>
-<tscreen><verb>
-int odr_oid(ODR o, Odr_oid **p, int optional, const char *name);
-</verb></tscreen>
-
-The C OID represenation is simply an array of integers, terminated by
-the value -1 (the <tt/Odr_oid/ type is synonymous with the <tt/int/
-type). We suggest that you use the OID database module (see section
-<ref id="oid" name="Object Identifiers">) to handle object identifiers
-in your application.
-
-<sect2>Tagging Primitive Types<label id="tag-prim">
-
-<p>
-The simplest way of tagging a type is to use the <tt/odr_implicit_tag()/ or
-<tt/odr_explicit_tag()/ macros:
-
-<tscreen><verb>
-int odr_implicit_tag(ODR o, Odr_fun fun, int class, int tag, int
-                     optional, const char *name);
-
-int odr_explicit_tag(ODR o, Odr_fun fun, int class, int tag,
-                     int optional, const char *name);
-</verb></tscreen>
-
-To create a type derived from the integer type by implicit tagging, you
-might write:
-
-<tscreen><verb>
-MyInt ::= &lsqb;210&rsqb; IMPLICIT INTEGER
-</verb></tscreen>
-
-In the <bf/ODR/ system, this would be written like:
-
-<tscreen><verb>
-int myInt(ODR o, int **p, int optional, const char *name)
-{
-    return odr_implicit_tag(o, odr_integer, p,
-                   ODR_CONTEXT, 210, optional, name);
-}
-</verb></tscreen>
-
-The function <tt/myInt()/ can then be used like any of the primitive
-functions provided by ODR. Note that the behavior of
-<tt/odr_explicit()/
-and <tt/odr_implicit()/ macros act exactly the same as the functions they
-are applied to - they respond to error conditions, etc, in the same
-manner - they simply have three extra parameters. The class parameter may
-take one of the values: <tt/ODR_CONTEXT/, <tt/ODR_PRIVATE/,
-<tt/ODR_UNIVERSAL/, or
-<tt/ODR_APPLICATION/.
-
-<sect2>Constructed Types
-
-<p>
-Constructed types are created by combining primitive types. The
-<bf/ODR/
-system only implements the SEQUENCE and SEQUENCE OF constructions
-(although adding the rest of the container types should be simple
-enough, if the need arises).
-
-For implementing SEQUENCEs, the functions
-
-<tscreen><verb>
-int odr_sequence_begin(ODR o, void *p, int size, const char *name);
-int odr_sequence_end(ODR o);
-</verb></tscreen>
-
-are provided.
-
-The <tt/odr_sequence_begin()/ function should be called in the beginning of a
-function that implements a SEQUENCE type. Its parameters are the
-<bf/ODR/
-stream, a pointer (to a pointer to the type you're implementing), and
-the <tt/size/ of the type (typically a C structure). On encoding, it
-returns 1 if *<tt/p/ is a null pointer. The <tt/size/ parameter is ignored. On
-decoding, it returns 1 if the type is found in the data stream.
-<tt/size/
-bytes of memory are allocated, and *<tt/p/ is set to point to this space.
-<tt/odr_sequence_end()/ is called at the end of the complex function. Assume
-that a type is defined like this:
-
-<tscreen><verb>
-MySequence ::= SEQUENCE {
-    intval INTEGER,
-    boolval BOOLEAN OPTIONAL }
-</verb></tscreen>
-
-The corresponding ODR encoder/decoder function and the associated data
-structures could be written like this:
-
-<tscreen><verb>
-typedef struct MySequence
-{
-    int *intval;
-    bool_t *boolval;
-} MySequence;
-
-int mySequence(ODR o, MySequence **p, int optional, const char *name)
-{
-    if (odr_sequence_begin(o, p, sizeof(**p), name) == 0)
-       return optional &ero;&ero; odr_ok(o);
-    return
-       odr_integer(o, &ero;(*p)->intval, 0, "intval") &ero;&ero;
-       odr_bool(o, &ero;(*p)->boolval, 1, "boolval") &ero;&ero;
-       odr_sequence_end(o);
-}
-</verb></tscreen>
-
-Note the 1 in the call to <tt/odr_bool()/, to mark that the sequence
-member is optional. If either of the member types had been tagged, the
-macros <tt/odr_implicit()/ or <tt/odr_explicit()/ could have been used.
-The new
-function can be used exactly like the standard functions provided with
-<bf/ODR/. It will encode, decode or pretty-print a data value of the
-<tt/MySequence/ type. We like to name types with an initial capital, as
-done in ASN.1 definitions, and to name the corresponding function with
-the first character of the name in lower case. You could, of course,
-name your structures, types, and functions any way you please - as
-long as you're consistent, and your code is easily readable.
-<tt/odr_ok/ is
-just that - a predicate that returns the state of the stream. It is
-used to ensure that the behaviour of the new type is compatible with
-the interface of the primitive types.
-
-<sect2>Tagging Constructed Types
-
-<p>
-<it>
-NOTE: See section <ref id="tag-prim" name="Tagging Primitive types">
-for information on how to tag the primitive types, as well as types
-that are already defined.
-</it>
-
-<sect3>Implicit Tagging
-
-<p>
-Assume the type above had been defined as
-
-<tscreen><verb>
-MySequence ::= &lsqb;10&rsqb; IMPLICIT SEQUENCE {
-    intval INTEGER,
-    boolval BOOLEAN OPTIONAL }
-</verb></tscreen>
-
-You would implement this in <bf/ODR/ by calling the function
-
-<tscreen><verb>
-int odr_implicit_settag(ODR o, int class, int tag);
-</verb></tscreen>
-
-which overrides the tag of the type immediately following it. The
-macro <tt/odr_implicit()/ works by calling <tt/odr_implicit_settag()/
-immediately
-before calling the function pointer argument. Your type function could
-look like this:
-
-<tscreen><verb>
-int mySequence(ODR o, MySequence **p, int optional, const char *name)
-{
-    if (odr_implicit_settag(o, ODR_CONTEXT, 10) == 0 ||
-       odr_sequence_begin(o, p, sizeof(**p), name) == 0)
-       return optional &ero;&ero; odr_ok(o);
-    return
-       odr_integer(o, &ero;(*p)->intval, 0, "intval") &ero;&ero;
-       odr_bool(o, &ero;(*p)->boolval, 1, "boolval") &ero;&ero;
-       odr_sequence_end(o);
-}
-</verb></tscreen>
-
-The definition of the structure <tt/MySequence/ would be the same.
-
-<sect3>Explicit Tagging
-
-<p>
-Explicit tagging of constructed types is a little more complicated,
-since you are in effect adding a level of construction to the data.
-
-Assume the definition:
-
-<tscreen><verb>
-MySequence ::= &lsqb;10&rsqb; IMPLICIT SEQUENCE {
-    intval INTEGER,
-    boolval BOOLEAN OPTIONAL }
-</verb></tscreen>
-
-Since the new type has an extra level of construction, two new functions
-are needed to encapsulate the base type:
-
-<tscreen><verb>
-int odr_constructed_begin(ODR o, void *p, int class, int tag,
-       const char *name);
-
-int odr_constructed_end(ODR o);
-</verb></tscreen>
-
-Assume that the IMPLICIT in the type definition above were replaced
-with EXPLICIT (or that the IMPLICIT keyword were simply deleted, which
-would be equivalent). The structure definition would look the same,
-but the function would look like this:
-
-<tscreen><verb>
-int mySequence(ODR o, MySequence **p, int optional, const char *name)
-{
-    if (odr_constructed_begin(o, p, ODR_CONTEXT, 10, name) == 0)
-       return optional &ero;&ero; odr_ok(o);
-    if (o->direction == ODR_DECODE)
-       *p = odr_malloc(o, sizeof(**p));
-    if (odr_sequence_begin(o, p, sizeof(**p), 0) == 0)
-    {
-       *p = 0; /* this is almost certainly a protocol error */
-       return 0;
-    }
-    return
-       odr_integer(o, &ero;(*p)->intval, 0, "intval") &ero;&ero;
-       odr_bool(o, &ero;(*p)->boolval, 1, "boolval") &ero;&ero;
-       odr_sequence_end(o) &ero;&ero;
-       odr_constructed_end(o);
-}
-</verb></tscreen>
-
-Notice that the interface here gets kind of nasty. The reason is
-simple: Explicitly tagged, constructed types are fairly rare in
-the protocols that we care about, so the
-aesthetic annoyance (not to mention the dangers of a cluttered
-interface) is less than the time that would be required to develop a
-better interface. Nevertheless, it is far from satisfying, and it's a
-point that will be worked on in the future. One option for you would
-be to simply apply the <tt/odr_explicit()/ macro to the first function,
-and not
-have to worry about <tt/odr_constructed_*/ yourself. Incidentally, as you
-might have guessed, the <tt/odr_sequence_/ functions are themselves
-implemented using the <tt/odr_constructed_/ functions.
-
-<sect2>SEQUENCE OF
-
-<p>
-To handle sequences (arrays) of a apecific type, the function
-
-<tscreen><verb>
-int odr_sequence_of(ODR o, int (*fun)(ODR o, void *p, int optional),
-                        void *p, int *num, const char *name);
-</verb></tscreen>
-
-The <tt/fun/ parameter is a pointer to the decoder/encoder
-function of the type. <tt/p/ is a pointer to an array of pointers to your
-type. <tt/num/ is the number of elements in the array.
-
-Assume a type
-
-<tscreen><verb>
-MyArray ::= SEQUENCE OF INTEGER
-</verb></tscreen>
-
-The C representation might be
-
-<tscreen><verb>
-typedef struct MyArray
-{
-    int num_elements;
-    int **elements;
-} MyArray;
-</verb></tscreen>
-
-And the function might look like
-
-<tscreen><verb>
-int myArray(ODR o, MyArray **p, int optional, const char *name)
-{
-    if (o->direction == ODR_DECODE)
-       *p = odr_malloc(o, sizeof(**p));
-    if (odr_sequence_of(o, odr_integer, &ero;(*p)->elements,
-       &ero;(*p)->num_elements, name))
-       return 1;
-    *p = 0;
-    return optional &ero;&ero; odr_ok(o);
-}
-</verb></tscreen>
-
-<sect2>CHOICE Types
-
-<p>
-The choice type is used fairly often in some ASN.1 definitions, so
-some work has gone into streamlining its interface.
-
-CHOICE types are handled by the function:
-
-<tscreen><verb>
-int odr_choice(ODR o, Odr_arm arm&lsqb;&rsqb;, void *p, void *whichp,
-               const char *name);
-</verb></tscreen>
-
-The <tt/arm/ array is used to describe each of the possible types that the
-CHOICE type may assume. Internally in your application, the CHOICE
-type is represented as a discriminated union. That is, a C union
-accompanied by an integer (or enum) identifying the active 'arm' of
-the union. <tt/whichp/ is a pointer to the union discriminator. When
-encoding, it is examined to determine the current type. When decoding,
-it is set to reference the type that was found in the input stream.
-
-The Odr_arm type is defined thus:
-
-<tscreen><verb>
-typedef struct odr_arm
-{
-    int tagmode;
-    int class;
-    int tag;
-    int which;
-    Odr_fun fun;
-    char *name;
-} Odr_arm;
-</verb></tscreen>
-
-The interpretation of the fields are:
-
-<descrip>
-<tag/tagmode/Either <tt/ODR_IMPLICIT/, <tt/ODR_EXPLICIT/, or <tt/ODR_NONE/
-(-1) to mark
-no tagging.
-<tag/class, tag/The class and tag of the type (-1 if no tagging is
-used).
-<tag/which/The value of the discriminator that corresponds to
-this CHOICE element. Typically, it will be a &num;defined constant, or
-an enum member.
-<tag/fun/A pointer to a function that implements the type of
-the CHOICE member. It may be either a standard <bf/ODR/ type or a type
-defined by yourself.
-<tag/name/Name of tag.
-</descrip>
-
-A handy way to prepare the array for use by the <tt/odr_choice()/ function
-is to
-define it as a static, initialized array in the beginning of your
-decoding/encoding function. Assume the type definition:
-
-<tscreen><verb>
-MyChoice ::= CHOICE {
-    untagged INTEGER,
-    tagged   &lsqb;99&rsqb; IMPLICIT INTEGER,
-    other    BOOLEAN
-}
-</verb></tscreen>
-
-Your C type might look like
-
-<tscreen><verb>
-typedef struct MyChoice
-{
-    enum
-    {
-       MyChoice_untagged,
-       MyChoice_tagged,
-       MyChoice_other
-    } which;
-    union
-    {
-       int *untagged;
-       int *tagged;
-       bool_t *other;
-    } u;
-};
-</verb></tscreen>
-
-And your function could look like this:
-
-<tscreen><verb>
-int myChoice(ODR o, MyChoice **p, int optional, const char *name)
-{
-    static Odr_arm arm&lsqb;&rsqb; =
-    {
-       {-1, -1, -1, MyChoice_untagged, odr_integer, "untagged"},
-       {ODR_IMPLICIT, ODR_CONTEXT, 99, MyChoice_tagged, odr_integer,
-                                                            "tagged"},
-       {-1, -1, -1, MyChoice_other, odr_boolean, "other"},
-       {-1, -1, -1, -1, 0}
-    };
-
-    if (o->direction == ODR_DECODE)
-       *p = odr_malloc(o, sizeof(**p);
-    else if (!*p)
-       return optional &ero;&ero; odr_ok(o);
-
-    if (odr_choice(o, arm, &ero;(*p)->u, &ero;(*p)->which), name)
-       return 1;
-    *p = 0;
-    return optional &ero;&ero; odr_ok(o);
-}
-</verb></tscreen>
-
-In some cases (say, a non-optional choice which is a member of a sequence),
-you can &dquot;embed&dquot; the union and its discriminator in the structure
-belonging to the enclosing type, and you won't need to fiddle with
-memory allocation to create a separate structure to wrap the
-discriminator and union.
-
-The corresponding function is somewhat nicer in the Sun XDR interface.
-Most of the complexity of this interface comes from the possibility of
-declaring sequence elements (including CHOICEs) optional.
-
-The ASN.1 specifictions naturally requires that each member of a
-CHOICE have a distinct tag, so they can be told apart on decoding.
-Sometimes it can be useful to define a CHOICE that has multiple types
-that share the same tag. You'll need some other mechanism, perhaps
-keyed to the context of the CHOICE type. In effect, we would like to
-introduce a level of context-sensitiveness to our ASN.1 specification.
-When encoding an internal representation, we have no problem, as long
-as each CHOICE member has a distinct discriminator value. For
-decoding, we need a way to tell the choice function to look for a
-specific arm of the table. The function
-
-<tscreen><verb>
-void odr_choice_bias(ODR o, int what);
-</verb></tscreen>
-
-provides this functionality. When called, it leaves a notice for the
-next call to <tt/odr_choice()/ to be called on the decoding
-stream <tt/o/ that only the <tt/arm/ entry with a <tt/which/ field
-equal to <tt/what/ should be tried.
-
-The most important application (perhaps the only one, really) is in
-the definition of application-specific EXTERNAL encoders/decoders
-which will automatically decode an ANY member given the direct or
-indirect reference.
-
-<sect1>Debugging
-
-<p>
-The protocol modules are suffering somewhat from a lack of diagnostic
-tools at the moment. Specifically ways to pretty-print PDUs that
-aren't recognized by the system. We'll include something to this end
-in a not-too-distant release. In the meantime, what we do when we get
-packages we don't understand is to compile the ODR module with
-<tt/ODR_DEBUG/ defined. This causes the module to dump tracing
-information as it processes data units. With this output and the
-protocol specification (Z39.50), it is generally fairly easy to see
-what goes wrong.
-
-<sect>The COMSTACK Module<label id="comstack">
-
-<sect1>Synopsis (blocking mode)
-
-<p>
-
-<tscreen><verb>
-
-COMSTACK *stack;
-char *buf = 0;
-int size = 0, length_incoming;
-char *protocol_package; 
-int protocol_package_length;
-char server_address[] = "myserver.com:2100";
-int status;
-
-stack = cs_create(tcpip_type, 1, PROTO_Z3950);
-if (!stack) {
-    perror("cs_create");  /* note use of perror() here since we have no stack yet */
-    exit(1);
-}
-
-status = cs_connect(stack, server_address);
-if (status != 0) {
-    cs_perror(stack, "cs_connect");
-    exit(1);
-}
-
-status = cs_put(stack, protocol_package, protocol_package_length);
-if (status) {
-    cs_perror(stack, "cs_put");
-    exit(1);
-}
-
-/* Now get a response */
-
-length_incoming = cs_get(stack, &amp;buf, &amp;size);
-if (!length_incoming) {
-    fprintf(stderr, "Connection closed\n");
-    exit(1);
-} else if (length_incoming < 0) {
-    cs_perror(stack, "cs_get");
-    exit(1);
-}
-
-/* Do stuff with buf here */
-
-/* clean up */
-cs_close(stack);
-if (buf)
-    free(buf);
-
-</verb></tscreen>
-
-<sect1>Introduction
-
-<p>
-The <bf/COMSTACK/
-subsystem provides a transparent interface to different types of transport
-stacks for the exchange of BER-encoded data. At present, the
-RFC1729 method (BER over TCP/IP), and Peter Furniss' XTImOSI
-stack are supported, but others may be added in time. The philosophy of the
-module is to provide a simple interface by hiding unused options and
-facilities of the underlying libraries. This is always done at the risk
-of losing generality, and it may prove that the interface will need
-extension later on.
-
-The interface is implemented in such a fashion that only the
-sub-layers constructed to the transport methods that you wish to
-use in your application are linked in.
-
-You will note that even though simplicity was a goal in the design,
-the interface is still orders of magnitudes more complex than the
-transport systems found in many other packages. One reason is that
-the interface needs to support the somewhat different requirements of
-the different lower-layer communications stacks; another important reason is
-that the interface seeks to provide a more or less industrial-strength
-approach to asynchronous event-handling. When no function is allowed
-to block, things get more complex - particularly on the server
-side. We urge you to have a look at the demonstration client and server
-provided with the package. They are meant to be easily readable and
-instructive, while still being at least moderately useful.
-
-<sect1>Common Functions
-
-<sect2>Managing Endpoints
-
-<p>
-<tscreen><verb>
-COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
-</verb></tscreen>
-
-Creates an instance of the protocol stack - a communications endpoint.
-The
-<tt/type/
-parameter determines the mode of communication. At present, the
-values
-<tt/tcpip_type/
-and
-<tt/mosi_type/
-are recognized. The function returns a null-pointer if a system error
-occurs. The <tt/blocking/ parameter should be one if you wish the
-association to operate in blocking mode, zero otherwise. The
-<tt/protocol/ field should be one of <tt/PROTO_SR/ or <tt/PROTO_Z3950/.
-
-<tscreen><verb>
-int cs_close(COMSTACK handle);
-</verb></tscreen>
-
-Closes the connection (as elegantly as the lower layers will permit),
-and releases the resouces pointed to by the
-<tt/handle/
-parameter. The
-<tt/handle/
-should not be referenced again after this call.
-
-<it>
-NOTE:
-We really need a soft disconnect, don't we?
-</it>
-
-<sect2>Data Exchange
-
-<p>
-<tscreen><verb>
-int cs_put(COMSTACK handle, char *buf, int len);
-</verb></tscreen>
-
-Sends
-<tt/buf/
-down the wire. In blocking mode, this function will return only when a
-full buffer has been written, or an error has occurred. In nonblocking
-mode, it's possible that the function will be unable to send the full
-buffer at once, which will be indicated by a return value of 1. The
-function will keep track of the number of octets already written; you
-should call it repeatedly with the same values of <tt/buf/ and
-<tt/len/, until the buffer has been transmitted. When a full buffer
-has been sent, the function will return 0 for success. -1 indicates
-an error condition (see below).
-
-<tscreen><verb>
-int cs_get(COMSTACK handle, char **buf, int *size);
-</verb></tscreen>
-
-Receives a PDU from the peer. Returns the number of bytes
-read. In nonblocking mode, it is possible that not all of the packet can be
-read at once. In this case, the function returns 1. To simplify the
-interface, the function is
-responsible for managing the size of the buffer. It will be reallocated
-if necessary to contain large packages, and will sometimes be moved
-around internally by the subsystem when partial packages are read. Before
-calling
-<tt/cs_get/
-for the fist time, the buffer can be initialized to the null pointer,
-and the length should also be set to 0 - cs_get will perform a
-<tt/malloc/(2)
-on the buffer for you. When a full buffer has been read, the size of
-the package is returned (which will always be greater than 1). -1
-indicates an error condition.
-
-See also the
-<tt/cs_more()/
-function below.
-
-<tscreen><verb>
-int cs_more(COMSTACK handle);
-</verb></tscreen>
-
-The <tt/cs_more()/ function should be used in conjunction with
-<tt/cs_get/
-and
-<tt/select/(2).
-The <tt/cs_get()/ function will sometimes (notably in the TCP/IP mode) read
-more than a single protocol package off the network. When this
-happens, the extra package is stored by the subsystem. After calling
-<tt/cs_get()/, and before waiting for more input,
-You should always call
-<tt/cs_more()/
-to check if there's a full protocol package already read. If
-<tt/cs_more()/
-returns 1,
-<tt/cs_get()/
-can be used to immediately fetch the new package. For the
-mOSI
-subsystem, the function should always return 0, but if you want your
-stuff to be protocol independent, you should use it.
-
-<it>
-NOTE: The <tt/cs_more()/
-function is required because the
-RFC1729-method
-does not provide a way of separating individual PDUs, short of
-partially decoding the BER. Some other implementations will carefully
-nibble at the packet by calling
-<tt/read/(2)
-several times. This was felt to be too inefficient (or at least
-clumsy) - hence the call for this extra function.
-</it>
-
-<tscreen><verb>
-int cs_look(COMSTACK handle);
-</verb></tscreen>
-
-This function is useful when you're operating in nonblocking
-mode. Call it when
-<tt/select/(2)
-tells you there's something happening on the line. It returns one of
-the following values:
-
-<descrip>
-<tag/CS_NONE/No event is pending. The data found on the line was
-not a complete package.
-<tag/CS_CONNECT/A response to your connect request has been received. Call
-<tt/cs_rcvconnect/
-to process the event and to finalize the connection establishment.
-<tag/CS_DISCON/The other side has closed the connection (or maybe
-sent a disconnect
-request - but do we care? Maybe later). Call
-<tt/cs_close/ To close your end of the association as well.
-<tag/CS_LISTEN/A connect request has been received. Call
-<tt/cs_listen/
-to process the event.
-<tag/CS_DATA/There's data to be found on the line. Call
-<tt/cs_get/
-to get it.
-</descrip>
-
-<it>
-NOTE:
-You should be aware that even if
-<tt/cs_look()/
-tells you that there's an event event pending, the corresponding
-function may still return and tell you there was nothing to be found.
-This means that only part of a package was available for reading. The
-same event will show up again, when more data has arrived.
-</it>
-
-<tscreen><verb>
-int cs_fileno(COMSTACK h);
-</verb></tscreen>
-
-Returns the file descriptor of the association. Use this when
-file-level operations on the endpoint are required (<tt/select/(2)
-operations, specifically).
-
-<sect1>Client Side
-
-<p>
-<tscreen><verb>
-int cs_connect(COMSTACK handle, void *address);
-</verb></tscreen>
-
-Initiate a connection with the target at <tt/address/ (more on
-addresses below). The function will return 0 on success, and 1 if
-the operation does not complete immediately (this will only
-happen on a nonblocking endpoint). In this case, use
-<tt/cs_rcvconnect/ to complete the operation, when <tt/select/(2)
-reports input pending on the association.
-
-<tscreen><verb>
-int cs_rcvconnect(COMSTACK handle);
-</verb></tscreen>
-
-Complete a connect operation initiated by <tt/cs_connect()/. It will
-return 0 on success; 1 if the operation has not yet completed (in this
-case, call the function again later); -1 if an error has occured.
-
-<sect1>Server Side
-
-<p>
-To establish a server under the <tt/inetd/ server, you can use
-
-<tscreen><verb>
-COMSTACK cs_createbysocket(int socket, CS_TYPE type, int blocking,
-                              int protocol);
-</verb></tscreen>
-
-The <it/socket/ parameter is an established socket (when your
-application is invoked from <tt/inetd/, the socket will typically be
-0. The following parameters are identical to the ones for
-<tt/cs_create/.
-
-<tscreen><verb>
-int cs_bind(COMSTACK handle, void *address, int mode)
-</verb></tscreen>
-
-Binds a local address to the endpoint. Read about addresses below. The
-<tt/mode/ parameter should be either <tt/CS_CLIENT/ or <tt/CS_SERVER/.
-
-<tscreen><verb>
-int cs_listen(COMSTACK handle, char *addr, int *addrlen);
-</verb></tscreen>
-
-Call this to process incoming events on an endpoint that has been
-bound in listening mode. It will return 0 to indicate that the connect
-request has been received, 1 to signal a partial reception, and -1 to
-indicate an error condition.
-
-<tscreen><verb>
-COMSTACK cs_accept(COMSTACK handle);
-</verb></tscreen>
-
-This finalises the server-side association establishment, after
-cs_listen has completed successfully. It returns a new connection
-endpoint, which represents the new association. The application will
-typically wish to fork off a process to handle the association at this
-point, and continue listen for new connections on the old <tt/handle/.
-
-You can use the call
-
-<tscreen><verb>
-char *cs_addrstr(COMSTACK);
-</verb></tscreen>
-
-on an established connection to retrieve the hostname of the remote host.
-
-<it>NOTE: You may need to use this function with some care if your
-name server service is slow or unreliable</it>
-
-<sect1>Addresses
-
-<p>
-The low-level format of the addresses are different depending on the
-mode of communication you have chosen. A function is provided by each
-of the lower layers to map a user-friendly string-form address to the
-binary form required by the lower layers.
-
-<tscreen><verb>
-struct sockaddr_in *tcpip_strtoaddr(char *str);
-
-struct netbuf *mosi_strtoaddr(char *str);
-</verb></tscreen>
-
-The format for TCP/IP addresses is straightforward:
-
-<tscreen><verb>
-<host> &lsqb; ':' <portnum> &rsqb;
-</verb></tscreen>
-
-The <tt/hostname/ can be either a domain name or an IP address. The
-port number, if omitted, defaults to 210.
-
-For OSI, the format is
-
-<tscreen><verb>
-&lsqb; <t-selector> '/' &rsqb; <host> &lsqb; ':' <port> &rsqb;
-</verb></tscreen>
-
-The transport selector is given as an even number of hex digits.
-
-You'll note that the address format for the OSI mode are just a subset
-of full presentation addresses. We use presentation addresses because
-xtimosi doesn't, in itself, allow access to the X.500 Directory
-service. We use a limited form, because we haven't yet come across an
-implementation that used more of the elements of a full p-address. It
-is a fairly simple matter to add the rest of the elements to the
-address format as needed, however: Xtimosi <it/does/ support the full
-P-address structure.
-
-In both transport modes, the special hostname &dquot;@&dquot; is mapped
-to any local address (the manifest constant INADDR_ANY). It is used
-to establish local listening endpoints in the server role.
-
-When a connection has been established, you can use
-
-<tscreen><verb>
-char cs_addrstr(COMSTACK h);
-</verb></tscreen>
-
-to retrieve the host name of the peer system. The function returns a pointer
-to a static area, which is overwritten on the next call to the function.
-
-<it>
-NOTE: We have left the issue of X.500 name-to-address mapping open, for the
-moment. It would be a simple matter to provide a table-based mapping,
-if desired. Alternately, we could use the X.500 client-function that
-is provided with the ISODE (although this would defeat some of the
-purpose of using ThinOSI in the first place. We have been told that it
-should be within the realm of the possible to implement a lightweight
-implementation of the necessary X.500 client capabilities on top of
-ThinOSI. This would be the ideal solution, we feel. On the other hand, it
-still remains to be seen just what role the Directory will play in a world
-populated by ThinOSI and other pragmatic solutions.
-</it>
-
-<sect1>Diagnostics
-
-<p>
-All functions return -1 if an error occurs. Typically, the functions
-will return 0 on success, but the data exchange functions
-(<tt/cs_get/, <tt/cs_put/, <tt/cs_more/)
-follow special rules. Consult their descriptions.
-
-When a function (including the data exchange functions) reports an
-error condition,
-use the function
-<tt/cs_errno()/
-to determine the cause of the
-problem. The function
-
-<tscreen><verb>
-void cs_perror(COMSTACK handle char *message);
-</verb></tscreen>
-
-works like
-<tt/perror/(2)
-and prints the
-<tt/message/
-argument, along with a system message, to
-<tt/stderr/.
-Use the character array
-
-<tscreen><verb>
-extern const char *cs_errlist&lsqb;&rsqb;;
-</verb></tscreen>
-
-to get hold of the message, if you want to process it differently.
-The function
-
-<tscreen><verb>
-const char *cs_stackerr(COMSTACK handle);
-</verb></tscreen>
-
-Returns an error message from the lower layer, if one has been
-provided.
-
-<sect1>Enabling OSI Communication
-
-<sect2>Installing Xtimosi
-<p>
-Although you will have to download Peter Furniss' XTI/mOSI
-implementation for yourself, we've tried to make the integration as
-simple as possible.
-
-The latest version of xtimosi will generally be under
-
-<tscreen><verb>
-ftp://pluto.ulcc.ac.uk/ulcc/thinosi/xtimosi/
-</verb></tscreen>
-
-When you have downloaded and unpacked the archive, it will (we assume)
-have created a directory called <tt/xtimosi/. We suggest that you place
-this directory <it/in the same directory/ where you unpacked the
-<bf/YAZ/
-distribution. This way, you shouldn't have to fiddle with the
-makefiles of <tt/YAZ/ beyond uncommenting a few lines.
-
-Go to <tt>xtimosi/src</tt>, and type &dquot;<tt/make libmosi.a/&dquot;.
-This should generally
-create the library, ready to use.
-
-<bf/CAVEAT/
-
-<it>
-The currently available release of xtimosi has some inherent
-problems that make it disfunction on certain platforms - eg. the
-Digital OSF/1 workstations. It is supposedly primarily a
-compiler problem, and we hope to see a release that is generally
-portable. While we can't guarantee that it can be brought to work
-on your platform, we'll be happy to talk to you about problems
-that you might see, and relay information to the author of the
-software. There are some signs that the <bf/gcc/ compiler is more
-likely to produce a fully functional library, but this hasn't
-been verified (we think that the problem is limited to the use
-of hexadecimal escape-codes used in strings, which are silently
-ignored by some compilers).
-</it>
-
-<it>
-A problem has been encountered in the communication with
-ISODE-based applications. If the ISODE presentation-user calls
-<tt/PReadRequest()/ with a timeout value different from <tt/OK/ or <tt/NOTOK/,
-he will get an immediate TIMEOUT abort when receiving large (&gt;2041
-bytes, which is the SPDU-size that the ISODE likes to work with) packages
-from an xtimosi-based implementation (probably most
-other implementations as well, in fact). It seems to be a flaw in the
-ISODE API, and the workaround (for ISODE users) is to either not
-use an explicit timeout (switching to either blocking or
-nonblocking mode), or to check that the timer really has expired
-before closing the connection.
-</it>
-
-The next step in the installation is to modify the makefile in the toplevel
-<bf/YAZ/
-directory. The place to change is in the top of the file, and is
-clearly marked with a comment.
-
-Now run <tt/make/ in the <bf/YAZ/ toplevel directory (do a
-&dquot;<tt/make clean/&dquot; first, if the
-system has been previously made without OSI support). Use the <bf/YAZ/
-<bf/ztest/
-and <bf/client/ demo programs to verify that OSI communication works OK. Then,
-you can go ahead and try to talk to other implementations.
-
-<it>
-NOTE: Our interoperability experience is limited to version
-7 of the Nordic SR-Nett package, which has had several
-protocol errors fixed from the earlier releases. If you have
-problems or successes in interoperating with other
-implementations, we'd be glad to hear about it, or to help
-you make things work, as our resources allow.
-</it>
-
-If you write your own applications based on <bf/YAZ/, and you wish to
-include OSI support, the procedure is equally simple. You should
-include the <tt/xmosi.h/ header file in addition to <tt/comstack.h/.
-<tt/xmosi.h/
-will define the manifest constant <tt/mosi_type/, which you should pass
-to the <tt/cs_create()/ function. In
-addition, you should use the function <tt/mosi_strtoaddr()/ rather than
-<tt/tcpip_strtoaddr()/ when you need to prepare an address.
-
-When you link your application, you should include (after the
-<tt/libyaz.a/
-library) the <tt/libmosi.a/ library, and the <tt/librfc.a/ library
-provided with
-<bf/YAZ/ (for OSI transport).
-
-As always, it can be very useful, if not essential, to have a look at the
-example applications
-to see how things are done.
-
-<sect2>OSI Transport
-
-<p>
-Xtimosi requires an implementation of the OSI transport service under
-the X/OPEN XTI API. We provide an implementation of the RFC1006
-encapsulation of OSI/TP0 in TCP/IP (through the Berkeley Sockets API),
-as an independent part of <bf/YAZ/ (it's found under the <tt/rfc1006/
-directory). If you have access to an OSI transport provider under XTI,
-you should be able to make that work too, although it may require
-tinkering with the <tt/mosi_strtoaddr()/ function.
-
-<sect2>Presentation Context Management
-
-<p>
-To simplify the implementation, we use Peter Furniss' alternative (PRF)
-option format
-for the Control of the presentation negotiation phase. This format
-is enabled by default when you
-compile xtimosi.
-
-The current version of <bf/YAZ/ does <it/not/ support presentation-layer
-negotiation of response record formats. The primary reason is that we
-have had access to no other SR or Z39.50 implementations over OSI that
-used this
-method. Secondarily, we believe that the EXPLAIN facility is a superior
-mechanism for relaying target capabilities in this respect. This is not to
-say that we have no intentions of supporting presentation context
-negotiation - we have just hitherto given it a lower priority than other
-aspects of the protocol.
-
-One thing is certain: The addition of this capability to <bf/YAZ/ should
-have only a minimal impact on existing applications, and on the
-interface to the software in general. Most likely, we will add an extra
-layer of interface to the processing of EXPLAIN records, which will
-convert back and forth between <tt/oident/ records (see section
-<ref id="oid" name="Object Identifiers">) and direct or indirect
-references, given the current association setup. Implementations based
-on any of the higher-level interfaces will most likely not have to be
-changed at all.
-
-<sect1>Summary and Synopsis
-
-<p>
-<tscreen><verb>
-#include <comstack.h>
-
-#include <tcpip.h>      /* this is for TCP/IP support   */
-#include <xmosi.h>      /* and this is for mOSI support */
-
-COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
-
-COMSTACK cs_createbysocket(int s, CS_TYPE type, int blocking,
-                              int protocol);
-
-int cs_bind(COMSTACK handle, int mode);
-
-int cs_connect(COMSTACK handle, void *address);
-
-int cs_rcvconnect(COMSTACK handle);
-
-int cs_listen(COMSTACK handle);
-
-COMSTACK cs_accept(COMSTACK handle);
-
-int cs_put(COMSTACK handle, char *buf, int len);
-
-int cs_get(COMSTACK handle, char **buf, int *size);
-
-int cs_more(COMSTACK handle);
-
-int cs_close(COMSTACK handle);
-
-int cs_look(COMSTACK handle);
-
-struct sockaddr_in *tcpip_strtoaddr(char *str);
-
-struct netbuf *mosi_strtoaddr(char *str);
-
-extern int cs_errno;
-
-void cs_perror(COMSTACK handle char *message);
-
-const char *cs_stackerr(COMSTACK handle);
-
-extern const char *cs_errlist[];
-</verb></tscreen>
-
-<sect>Making an IR Interface for Your Database with YAZ<label id="server">
-
-<sect1>Introduction
-
-<p>
-<it>
-NOTE: If you aren't into documentation, a good way to learn how the
-backend interface works is to look at the backend.h file. Then,
-look at the small dummy-server in server/ztest.c. Finally, you can
-have a look at the seshigh.c file, which is where most of the
-logic of the frontend server is located. The backend.h file also
-makes a good reference, once you've chewed your way through
-the prose of this file.
-</it>
-
-If you have a database system that you would like to make available by
-means of Z39.50/SR, <bf/YAZ/ basically offers your two options. You
-can use the APIs provided by the <bf/ASN/, <bf/ODR/, and <bf/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.
-
-<it>
-NOTE: The backend interface was designed in anticipation of a specific
-integration task, while still attempting to achieve some degree of
-generality. We realise 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
-toplevel 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.
-</it>
-
-<sect1>The Database Frontend
-
-<p>
-We refer to this software as a generic database frontend. Your
-database system is the <it/backend database/, and the interface between
-the two is called the <it/backend API/. The backend API consists of a
-small number of function prototypes and structure definitions. You are
-required to provide the <bf/main()/ routine for the server (which can be
-quite simple), as well as functions 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 functions will perform the tasks of:
-
-<itemize>
-<item>Initialization.
-<item>Searching.
-<item>Fetching records.
-<item>Scanning the database index (if you wish to implement SCAN).
-</itemize>
-
-(more functions will be added in time to support as much of
-Z39.50-1995 as possible).
-
-Because the model where pipes or sockets are used to access the backend
-database is a fairly common one, we have added a mechanism that allows this
-communication to take place asynchronously. In this mode, the frontend
-server doesn't have to block while the backend database is processing
-a request, but can wait for additional PDUs from the client.
-
-<sect1>The Backend API
-
-<p>
-The headers files that you need to use the interface are in the
-include/ directory. They are called <tt/statserv.h/ and <tt/backend.h/. They
-will include other files from the <tt/include/ 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 <tt/make/ in the toplevel <bf/YAZ/ directory,
-everything you need to create your server is put the lib/libyaz.a
-library. If you want OSI as well, you'll also need to link in the
-<tt/libmosi.a/ library from the xtimosi distribution (see the mosi.txt
-file), a well as the <tt>lib/librfc.a</tt> library (to provide OSI transport
-over RFC1006/TCP).
-
-<sect1>Your main() Routine
-
-<p>
-As mentioned, your <bf/main()/ 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
-
-<tscreen><verb>int statserv_main(int argc, char **argv);</verb></tscreen>
-
-<bf/Statserv_main/ will establish listening sockets according to the
-parameters given. When connection requests are received, the event
-handler will typically <bf/fork()/ to handle the new request. If you do use
-global variables, you should be aware, then, that these cannot be
-shared between associations, unless you explicitly disallow forking by
-command line parameters (we advise against this for any purposes
-except debugging, as a crash or hang in the server process will affect
-all users currently signed on to the server).
-
-The server provides a mechanism for controlling some of its behavior
-without using command-line options. The function
-
-<tscreen><verb>
-statserv_options_block *statserv_getcontrol(void);
-</verb></tscreen>
-
-Will return a pointer to a <tt/struct statserv_options_block/ describing
-the current default settings of the server. The structure contains
-these elements:
-
-<descrip>
-<tag/int dynamic/A boolean value, which determines whether the server
-will fork on each incoming request (TRUE), or not (FALSE). Default is
-TRUE.
-<tag/int loglevel/Set this by ORing the constants defined in include/log.h.
-<tag/char logfile&lsqb;ODR_MAXNAME+1&rsqb;/File for diagnostic output
-(&dquot;&dquot;: stderr).
-<tag/char apdufile&lsqb;ODR_MAXNAME+1&rsqb;/Name of file for logging incoming and
-outgoing APDUs (&dquot;&dquot;: don't log APDUs, &dquot;-&dquot;: <tt/stderr/).
-<tag/char default_listen&lsqb;1024&rsqb;/Same form as the command-line
-specification of listener address. &dquot;&dquot;: no default listener address.
-Default is to listen at &dquot;tcp:@:9999&dquot;. You can only
-specify one default listener address in this fashion.
-<tag/enum oid_proto default_proto;/Either <tt/PROTO_SR/ or <tt/PROTO_Z3950/.
-Default is <tt/PROTO_Z39_50/.
-<tag/int idle_timeout;/Maximum session idletime, in minutes. Zero indicates
-no (infinite) timeout. Default is 120 minutes.
-<tag/int maxrecordsize;/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.
-<tag/char configname&lsqb;ODR_MAXNAME+1&rsqb;/Passed to the backend when a
-new connection is received.
-<tag/char setuid&lsqb;ODR_MAXNAME+1&rsqb;/Set user id to the user specified,
-after binding the listener addresses.
-</descrip>
-
-The pointer returned by <tt/statserv_getcontrol/ 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
-
-<tscreen><verb>
-void statserv_setcontrol(statserv_options_block *block);
-</verb></tscreen>
-
-Note that you should generally update this structure <it/before/ calling
-<tt/statserv_main()/.
-
-<sect1>The Backend Functions
-
-<p>
-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.
-
-<tscreen><verb>bend_initresult *bend_init(bend_initrequest *r);</verb></tscreen>
-
-This function is called once for each new connection request, after
-a new process has been forked, and an initRequest has been received
-from the client. The parameter and result structures are defined as
-
-<tscreen>
-<verb>
-typedef struct bend_initrequest
-{
-    char *configname;
-} 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;
-</verb>
-</tscreen>
-
-The <tt/configname/ of <tt/bend_initrequest/ is currently always set to
-&dquot;default-config&dquot;. 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).
-
-In general, the server frontend expects that the <tt/bend_*result/
-pointer that you return is valid at least until the next call to a
-<tt/bend_* function/. 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.
-
-The <tt/errcode/ should be zero if the initialization of the backend went
-well. Any other value will be interpreted as an error. The
-<tt/errstring/ isn't used in the current version, but one option
-would be to stick it
-in the initResponse as a VisibleString. The <tt/handle/ 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.
-
-<tscreen>
-<verb>
-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;
-</verb>
-</tscreen>
-
-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
-<tt/bend_searchrequest/ tructure, and call the <tt/bend_search
-function/. The <tt/fd/
-argument will point to an integer variable. If you are able to do
-asynchronous I/O with your database server, you should set *<tt/fd/ to the
-file descriptor you use for the communication, and return a null
-pointer. The server frontend will then <tt/select()/ on the *<tt/fd/,
-and will call
-<tt/bend_searchresult/ when it sees that data is available. If you don't
-support asynchronous I/O, you should return a pointer to the
-<tt/bend_searchresult/ immediately, and leave *<tt/fd/ untouched. This
-construction is common to all of the <tt/bend_/ functions (except
-<tt/bend_init/). Note that you can choose to support this facility in none,
-any, or all of the <tt/bend_/ functions, and you can respond
-differently on each request at run-time. The server frontend will
-adapt accordingly.
-
-The <tt/bend_searchrequest/ is a fairly close approximation of a protocol
-searchRequest PDU. The <tt/setname/ 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 <tt/replace_set/ is a
-boolean value corresponding to the resultSetIndicator field in the
-protocol. <tt>Num_bases/basenames</tt> is a length of/array of character
-pointers to the database names provided by the client. The <tt/query/ 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 <tt>include/proto.h</tt>. 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 <tt/oid_getentbyoid/ function
-provided by <bf/YAZ/.
-
-The result structure contains a number of hits, and an
-<tt>errcode/errstring</tt> 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
-<tt/errstring/, 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.
-
-<tscreen>
-<verb>
-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;
-</verb>
-</tscreen>
-
-<it>
-NOTE: The <tt/bend_fetchresponse()/ function is not yet supported
-in this version of the software. Your implementation of <tt/bend_fetch()/
-should always return a pointer to a <tt/bend_fetchresult/.
-</it>
-
-The frontend server calls <tt/bend_fetch/ when it needs database records to
-fulfill a searchRequest or a presentRequest. The <tt/setname/ is simply the
-name of the result set that holds the reference to the desired record.
-The <tt/number/ is the offset into the set (with 1 being the first record
-in the set). The <tt/format/ field is the record format requested by the
-client (See section <ref id="oid" name="Object Identifiers">). The value
-<tt/VAL_NONE/ indicates that the client did not request a specific format.
-The <tt/stream/ argument is an <bf/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.
-
-In the result structure, the <tt/basename/ is the name of the
-database that holds the
-record. <tt/Len/ is the length of the record returned, in bytes, and
-<tt/record/
-is a pointer to the record. <tt/Last_in_set/ should be nonzero only if the
-record returned is the last one in the given result set. <tt/Errcode/ and
-<tt/errstring/, if given, will currently be interpreted as a global error
-pertaining to the set, and will be returned in a
-nonSurrogateDiagnostic.
-
-<it>NOTE: This is silly. Add a flag to say which is which.</it>
-
-If the <tt/len/ field has the value -1, then <tt/record/ is assumed to point
-to a constructed data type. The <tt/format/ field will be used to determine
-which encoder should be used to serialize the data.
-
-<it>
-NOTE: If your backend generates structured records, it should use
-<tt/odr_malloc()/ on the provided stream for allocating data: This allows
-the frontend server to keep track of the record sizes.
-</it>
-
-The <tt/format/ field is mapped to an object identifier in the direct
-reference of the resulting EXTERNAL representation of the record.
-
-<it>NOTE: The current version of <bf/YAZ/ only supports the direct reference
-mode.</it>
-
-<tscreen>
-<verb>
-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;
-</verb>
-</tscreen>
-
-<it>
-NOTE: The &dquot;delete&dquot; function is not yet supported
-in this version of the software.
-</it>
-
-<it>
-NOTE: 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?
-</it>
-
-<tscreen>
-<verb>
-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 */
-    char **basenames;   /* databases to search */
-    Z_AttributesPlusTerm *term;
-    int term_position;  /* desired index of term in result list */
-    int num_entries;    /* number of entries requested */
-} bend_scanrequest;
-
-typedef struct bend_scanresult
-{
-    int num_entries;
-    struct scan_entry
-    {
-       char *term;
-       int occurrences;
-    } *entries;
-    int term_position;
-    enum
-    {
-       BEND_SCAN_SUCCESS,
-       BEND_SCAN_PARTIAL
-    } status;
-    int errcode;
-    char *errstring;
-} bend_scanresult;
-</verb>
-</tscreen>
-
-<it>
-NOTE: The <tt/bend_scanresponse()/ function is not yet supported
-in this version of the software. Your implementation of <tt/bend_scan()/
-should always return a pointer to a <tt/bend_scanresult/.
-</it>
-
-<sect1>Application Invocation
-
-<p>
-The finished application has the following
-invocation syntax (by way of <tt/statserv_main()/):
-
-<tscreen> <verb>
-appname &lsqb;-szSu -a apdufile -l logfile -v loglevel&rsqb;
-&lsqb;listener ...&rsqb;
-</verb> </tscreen>
-
-The options are
-
-<descrip>
-<tag/-a/APDU file. Specify a file for dumping PDUs (for diagnostic purposes).
-The special name &dquot;-&dquot; sends output to <tt/stderr/.
-
-<tag/-S/Don't fork on connection requests. This is good for debugging, but
-not recommended for real operation: Although the server is
-asynchronous and non-blocking, it can be nice to keep a software
-malfunction (okay then, a crash) from affecting all current users.
-
-<tag/-s/Use the SR protocol.
-
-<tag/-z/Use the Z39.50 protocol (default). These two options complement
-eachother. You can use both multiple times on the same command
-line, between listener-specifications (see below). This way, you
-can set up the server to listen for connections in both protocols
-concurrently, on different local ports.
-
-<tag/-l/The logfile.
-
-<tag/-v/The log level. Use a comma-separated list of members of the set
-{fatal,debug,warn,log,all,none}.
-<tag/-u/Set user ID. Sets the real UID of the server process to that of the
-given user. It's useful if you aren't comfortable with having the
-server run as root, but you need to start it as such to bind a
-privileged port.
-
-<tag/-w/Working directory.
-<tag/-i/Use this when running from the <tt/inetd/ server.
-
-<tag/-t/Idle session timeout, in minutes.
-
-<tag/-k/Maximum record size/message size, in kilobytes.
-
-</descrip>
-
-A listener specification consists of a transport mode followed by a
-colon (:) followed by a listener address. The transport mode is
-either <tt/osi/ or <tt/tcp/.
-
-For TCP, an address has the form
-
-<tscreen><verb>
-hostname | IP-number &lsqb;: portnumber&rsqb;
-</verb></tscreen>
-
-The port number defaults to 210 (standard Z39.50 port).
-
-For osi, the address form is
-
-<tscreen><verb>
-&lsqb;t-selector /&rsqb; hostname | IP-number &lsqb;: portnumber&rsqb;
-</verb></tscreen>
-
-The transport selector is given as a string of hex digits (with an even
-number of digits). The default port number is 102 (RFC1006 port).
-
-Examples
-
-<tscreen>
-<verb>
-tcp:dranet.dra.com
-
-osi:0402/dbserver.osiworld.com:3000
-</verb>
-</tscreen>
-
-In both cases, the special hostname &dquot;@&dquot; is mapped to
-the address INADDR_ANY, which causes the server to listen on any local
-interface. To start the server listening on the registered ports for
-Z39.50 and SR over OSI/RFC1006, and to drop root privileges once the
-ports are bound, execute the server like this (from a root shell):
-
-<tscreen><verb>
-my-server -u daemon tcp:@ -s osi:@
-</verb></tscreen>
-
-You can replace <tt/daemon/ with another user, eg. your own account, or
-a dedicated IR server account. <tt/my-server/ should be the name of your
-server application. You can test the procedure with the <tt/ztest/
-application.
-
-<sect1>Summary and Synopsis
-
-<p>
-<tscreen><verb>
-#include <backend.h>
-
-bend_initresult *bend_init(bend_initrequest *r);
-
-bend_searchresult *bend_search(void *handle, bend_searchrequest *r,
-                                 int *fd);
-
-bend_searchresult *bend_searchresponse(void *handle);
-
-bend_fetchresult *bend_fetch(void *handle, bend_fetchrequest *r,
-                               int *fd);
-
-bend_fetchresult *bend_fetchresponse(void *handle);
-
-bend_scanresult *bend_scan(void *handle, bend_scanrequest *r, int *fd);
-
-bend_scanresult *bend_scanresponse(void *handle);
-
-bend_deleteresult *bend_delete(void *handle, bend_deleterequest *r,
-                                  int *fd);
-
-bend_deleteresult *bend_deleteresponse(void *handle);
-
-void bend_close(void *handle);
-</verb></tscreen>
-
-<sect>Future Directions
-
-<p>
-The software has been
-successfully ported to the Mac as well as Windows NT/95 - we'd like to
-test those ports better and make sure they work as they should.
-
-We have a new and better version of the frontend server on the drawing
-board. Resources and external commitments will govern when we'll be
-able to do something real with it. Fetures should include greater
-flexibility, greter support for access/resource control, and easy
-support for Explain (possibly with Zebra as an extra database engine).
-
-We now support all PDUs of Z39.50-1995. If there is one of the
-supporting structures that you need but can't find in the prt*.h
-files, send us a note; it may be on its way.
-
-The 'retrieval' module needs to be finalized and documented. We think
-it can form a useful resource for people dealing with complex record
-structures, but for now, you'll mostly have to chew through the code
-yourself to make use of it. Not acceptable.
-
-Other than that, YAZ generally moves in the directions which appear to
-make the most people happy (including ourselves, as prime users of the
-software). If there's something you'd like to see in here, then drop
-us a note and let's see what we can come up with.
-
-<sect>License
-
-<sect1>Index Data Copyright
-
-<p>
-Copyright &copy; 1995-2000 Index Data.
-
-Permission to use, copy, modify, distribute, and sell this software and
-its documentation, in whole or in part, for any purpose, is hereby granted,
-provided that:
-
-1. This copyright and permission notice appear in all copies of the
-software and its documentation. Notices of copyright or attribution
-which appear at the beginning of any file must remain unchanged.
-
-2. The names of Index Data or the individual authors may not be used to
-endorse or promote products derived from this software without specific
-prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
-EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
-WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-IN NO EVENT SHALL INDEX DATA BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
-INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR
-NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
-LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-OF THIS SOFTWARE.
-
-<sect1>Additional Copyright Statements
-
-<p>
-The optional CCL query language interpreter is covered by the following
-license:
-
-Copyright &copy; 1995, the EUROPAGATE consortium (see below).
-
-The EUROPAGATE consortium members are:
-
-   University College Dublin
-   Danmarks Teknologiske Videnscenter
-   An Chomhairle Leabharlanna
-   Consejo Superior de Investigaciones Cientificas
-
-Permission to use, copy, modify, distribute, and sell this software and
-its documentation, in whole or in part, for any purpose, is hereby granted,
-provided that:
-
-1. This copyright and permission notice appear in all copies of the
-software and its documentation. Notices of copyright or attribution
-which appear at the beginning of any file must remain unchanged.
-
-2. The names of EUROPAGATE or the project partners may not be used to
-endorse or promote products derived from this software without specific
-prior written permission.
-
-3. Users of this software (implementors and gateway operators) agree to
-inform the EUROPAGATE consortium of their use of the software. This
-information will be used to evaluate the EUROPAGATE project and the
-software, and to plan further developments. The consortium may use
-the information in later publications.
-
-4. Users of this software agree to make their best efforts, when
-documenting their use of the software, to acknowledge the EUROPAGATE
-consortium, and the role played by the software in their work.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
-EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
-WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-IN NO EVENT SHALL THE EUROPAGATE CONSORTIUM OR ITS MEMBERS BE LIABLE
-FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF
-ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
-OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND
-ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
-USE OR PERFORMANCE OF THIS SOFTWARE.
-
-<sect>About Index Data
-
-<p>
-Index Data is a consulting and software-development enterprise that
-specialises in library and information management systems. Our
-interests and expertise span a broad range of related fields, and one
-of our primary, long-term objectives is the development of a powerful
-information management
-system with open network interfaces and hypermedia capabilities.
-
-We make this software available free of charge, on a fairly unrestrictive
-license; as a service to the networking community, and to further the
-development of quality software for open network communication.
-
-We'll be happy to answer questions about the software, and about ourselves
-in general.
-
-<tscreen><verb>
-Index Data Aps
-K&oslash;bmagergade 43
-DK-1150 Copenhagen K
-</verb></tscreen>
-
-<p>
-<tscreen><verb>
-Phone: +45 3341 0100
-Fax  : +45 3341 0101
-Email: info@indexdata.dk
-</verb></tscreen>
-
-The <it>Hacker's Jargon File</it> has the following to say about the
-use of the
-prefix &dquot;YA&dquot; in the name of a software product.
-
-<it>
-Yet Another. adj. 1. Of your own work: A
-humorous allusion often used in titles to acknowledge that the
-topic is not original, though the content is.  As in &dquot;Yet Another
-AI Group&dquot; or &dquot;Yet Another Simulated Annealing Algorithm&dquot;.
-2. Of
-others' work: Describes something of which there are already far
-too many.
-</it>
-
-</article>
index a77b560..13f2769 100644 (file)
      <!ENTITY app-license SYSTEM "license.xml">
      <!ENTITY app-indexdata SYSTEM "indexdata.xml">
      <!ENTITY app-credits SYSTEM "credits.xml">
+     <!ENTITY ztest-options SYSTEM "ztest-options.xml">
+     <!ENTITY yaz-client-commands SYSTEM "yaz-client-commands.xml">
      <!ENTITY asn "Z39.50 ASN.1">
      <!ENTITY odr "<acronym>ODR</acronym>">
      <!ENTITY comstack "<acronym>COMSTACK</acronym>">
      <!ENTITY zoom "<acronym>ZOOM</acronym>">
 ]>
-<!-- $Id: yaz.xml.in,v 1.4 2002-05-02 10:35:44 adam Exp $ -->
+<!-- $Id: yaz.xml.in,v 1.5 2002-09-16 14:16:31 adam Exp $ -->
 <book id="yaz">
  <bookinfo>
   <title>YAZ User's Guide and Reference</title>
diff --git a/doc/ztest-options.xml b/doc/ztest-options.xml
new file mode 100644 (file)
index 0000000..3d08766
--- /dev/null
@@ -0,0 +1,140 @@
+<!-- 
+   $Id: ztest-options.xml,v 1.1 2002-09-16 14:16:31 adam Exp $
+   Options for generic frontend server and yaz-ztest.
+   Included in both manual and man page for yaz-ztest
+-->
+
+<variablelist>
+ <varlistentry><term><literal>-a </literal>
+   <replaceable>file</replaceable></term>
+  <listitem><para>
+    Specify a file for dumping PDUs (for diagnostic purposes).
+    The special name <literal>-</literal> (dash) sends output to
+    <literal>stderr</literal>.
+   </para></listitem></varlistentry>
+ <varlistentry><term><literal>-S</literal></term>
+  <listitem><para>
+    Don't fork or make threads on connection requests. This is good for
+    debugging, but not recommended for real operation: Although the
+    server is asynchronous and non-blocking, it can be nice to keep
+    a software malfunction (okay then, a crash) from affecting all
+    current users.
+   </para></listitem></varlistentry>
+ <varlistentry><term><literal>-1</literal></term>
+  <listitem><para>
+    Like <literal>-S</literal> but after one session the server
+    exits. This mode is for debugging <emphasis>only</emphasis>.
+   </para></listitem></varlistentry>
+ <varlistentry><term><literal>-T</literal></term>
+  <listitem><para>
+    Operate the server in threaded mode. The server creates a thread
+    for each connection rather than a fork a process. Only available
+    on UNIX systems that offers POSIX threads.
+   </para></listitem></varlistentry>
+
+ <varlistentry><term><literal>-s</literal></term>
+  <listitem><para>
+    Use the SR protocol (obsolete).
+   </para></listitem></varlistentry>
+
+ <varlistentry><term><literal>-z</literal></term>
+  <listitem><para>
+    Use the Z39.50 protocol (default). This option and <literal>-s</literal>
+    complement each other.
+    You can use both multiple times on the same command
+    line, between listener-specifications (see below). This way, you
+    can set up the server to listen for connections in both protocols
+    concurrently, on different local ports.
+   </para></listitem></varlistentry>
+
+ <varlistentry><term><literal>-l </literal>
+   <replaceable>file</replaceable></term>
+  <listitem><para>The logfile.
+   </para></listitem></varlistentry>
+
+ <varlistentry><term><literal>-c </literal>
+   <replaceable>config</replaceable></term>
+  <listitem><para>A user option that serves as a specifier for some
+    sort of configuration, e.g. a filename.
+    The argument to this option is transferred to member
+    <literal>configname</literal>of the
+    <literal>statserv_options_block</literal>.
+   </para></listitem></varlistentry>
+
+ <varlistentry><term><literal>-v </literal>
+   <replaceable>level</replaceable></term>
+  <listitem><para>
+    The log level. Use a comma-separated list of members of the set
+    {fatal,debug,warn,log,malloc,all,none}.
+   </para></listitem></varlistentry>
+
+ <varlistentry><term><literal>-u </literal>
+   <replaceable>uid</replaceable></term>
+  <listitem><para>
+    Set user ID. Sets the real UID of the server process to that of the
+    given user. It's useful if you aren't comfortable with having the
+    server run as root, but you need to start it as such to bind a
+    privileged port.
+   </para></listitem></varlistentry>
+
+ <varlistentry><term><literal>-w </literal>
+   <replaceable>dir</replaceable></term>
+  <listitem><para>
+    The server changes to this directory during before listening 
+    on incoming connections. This option is useful
+    when the server is operating from the <application>inetd</application>
+    daemon (see <literal>-i</literal>).
+   </para></listitem></varlistentry>
+
+ <varlistentry><term><literal>-i</literal></term>
+  <listitem><para>
+    Use this to make the the server run from the
+    <application>inetd</application> server (UNIX only).
+   </para></listitem></varlistentry>
+ <varlistentry><term><literal>-install</literal></term>
+  <listitem><para>
+    Use this to install the server as an NT service
+    (Windows 2000/NT only). 
+    Control the server by going to the Services in the Control Panel.
+   </para></listitem></varlistentry>
+ <varlistentry><term><literal>-remove</literal></term>
+  <listitem><para>
+    Use this to remove the server from the NT services
+    (Windows 2000/NT only). 
+   </para></listitem></varlistentry>
+ <varlistentry><term><literal>-t </literal>
+   <replaceable>minutes</replaceable></term>
+  <listitem><para>
+    Idle session timeout, in minutes.
+   </para></listitem></varlistentry>
+ <varlistentry><term><literal>-k </literal>
+   <replaceable>size</replaceable></term>
+  <listitem><para>
+    Maximum record size/message size, in kilobytes.
+   </para></listitem>
+ </varlistentry>
+</variablelist>
+
+<!-- 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:
+-->