# The Z39.50 Server

## Running the Z39.50 Server (zebrasrv)

Syntax

        zebrasrv [options] [listener-address ...]

Options

-a APDU file

  Specify a file for dumping PDUs (for diagnostic purposes). The special name "-" sends output to `stderr`.

-c config-file

  Read configuration information from config-file. The default configuration is `./zebra.cfg`.

-S

  Don't fork on connection requests. This can be useful for symbolic-level debugging. The server can only accept a single connection in this mode.

-z

  Use the Z39.50 protocol. Currently the only protocol supported. The option is retained for historical reasons, and for future extensions.

-l logfile

  Specify an output file for the diagnostic messages. The default is to write this information to `stderr`.

-v log-level

  The log level. Use a comma-separated list of members of the set {fatal,debug,warn,log,all,none}.

-u username

  Set user ID. Sets the real UID of the server process to that of the given username. 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.

-w working-directory

  Change working directory.

-i

  Run under the Internet superserver, `inetd`. Make sure you use the logfile option `-l` in conjunction with this mode and specify the `-l` option before any other options.

-t timeout

  Set the idle session timeout (default 60 minutes).

-k kilobytes

  Set the (approximate) maximum size of present response messages. Default is 1024 KB (1 MB).

A listener-address consists of an optional transport mode followed by a colon (:) followed by a listener address. The transport mode is either `ssl` or `tcp` (default).

For TCP, an address has the form

        hostname | IP-number [: portnumber]

The port number defaults to 210 (standard Z39.50 port) for privileged users (root), and 9999 for normal users.

Examples

        tcp:@

        ssl:@:3000

In both cases, the special hostname "@" 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 port for Z39.50, and to drop root privileges once the ports are bound, execute the server like this (from a root shell):

        zebrasrv -u daemon @

You can replace `daemon` with another user, eg. your own account, or a dedicated IR server account.

The default behavior for `zebrasrv` is to establish a single TCP/IP listener, for the Z39.50 protocol, on port 9999.

## Z39.50 Protocol Support and Behavior

### Initialization

During initialization, the server will negotiate to version 3 of the Z39.50 protocol, and the option bits for Search, Present, Scan, NamedResultSets, and concurrentOperations will be set, if requested by the client. The maximum PDU size is negotiated down to a maximum of 1 MB by default.

### Search

The supported query type are 1 and 101. All operators are currently supported with the restriction that only proximity units of type "word" are supported for the proximity operator. Queries can be arbitrarily complex. Named result sets are supported, and result sets can be used as operands without limitations. Searches may span multiple databases.

The server has full support for piggy-backed retrieval (see also the following section).

Use attributes are interpreted according to the attribute sets which have been loaded in the `zebra.cfg` file, and are matched against specific fields as specified in the `.abs` file which describes the profile of the records which have been loaded. If no Use attribute is provided, a default of Bib-1 Any is assumed.

If a Structure attribute of Phrase is used in conjunction with a Completeness attribute of Complete (Sub)field, the term is matched against the contents of the phrase (long word) register, if one exists for the given Use attribute. A phrase register is created for those fields in the `.abs` file that contains a `p`-specifier.

If Structure=Phrase is used in conjunction with Incomplete Field - the default value for Completeness, the search is directed against the normal word registers, but if the term contains multiple words, the term will only match if all of the words are found immediately adjacent, and in the given order. The word search is performed on those fields that are indexed as type `w` in the `.abs` file.

If the Structure attribute is Word List, Free-form Text, or Document Text, the term is treated as a natural-language, relevance-ranked query. This search type uses the word register, i.e. those fields that are indexed as type `w` in the `.abs` file.

If the Structure attribute is Numeric String the term is treated as an integer. The search is performed on those fields that are indexed as type `n` in the `.abs` file.

If the Structure attribute is URx the term is treated as a URX (URL) entity. The search is performed on those fields that are indexed as type `u` in the `.abs` file.

If the Structure attribute is Local Number the term is treated as native Zebra Record Identifier.

If the Relation attribute is Equals (default), the term is matched in a normal fashion (modulo truncation and processing of individual words, if required). If Relation is Less Than, Less Than or Equal, Greater than, or Greater than or Equal, the term is assumed to be numerical, and a standard regular expression is constructed to match the given expression. If Relation is Relevance, the standard natural-language query processor is invoked.

For the Truncation attribute, No Truncation is the default. Left Truncation is not supported. Process # in search term is supported, as is Regxp-1. Regxp-2 enables the fault-tolerant (fuzzy) search. As a default, a single error (deletion, insertion, replacement) is accepted when terms are matched against the register contents.

#### Regular expressions

Each term in a query is interpreted as a regular expression if the truncation value is either Regxp-1 (102) or Regxp-2 (103). Both query types follow the same syntax with the operands:

x

  Matches the character x.

.

  Matches any character.

`[`..`]`

  Matches the set of characters specified; such as `[abc]` or `[a-c]`.

and the operators:

x*

  Matches x zero or more times. Priority: high.

x+

  Matches x one or more times. Priority: high.

x?

  Matches x zero or once. Priority: high.

xy

  Matches x, then y. Priority: medium.

x|y

  Matches either x or y. Priority: low.

The order of evaluation may be changed by using parentheses.

If the first character of the Regxp-2 query is a plus character (`+`) it marks the beginning of a section with non-standard specifiers. The next plus character marks the end of the section. Currently Zebra only supports one specifier, the error tolerance, which consists one digit.

Since the plus operator is normally a suffix operator the addition to the query syntax doesn't violate the syntax for standard regular expressions.

#### Query examples

Phrase search for information retrieval in the title-register:

          @attr 1=4 "information retrieval"

Ranked search for the same thing:

          @attr 1=4 @attr 2=102 "Information retrieval"

Phrase search with a regular expression:

          @attr 1=4 @attr 5=102 "informat.* retrieval"

Ranked search with a regular expression:

          @attr 1=4 @attr 5=102 @attr 2=102 "informat.* retrieval"

In the GILS schema (`gils.abs`), the west-bounding-coordinate is indexed as type `n`, and is therefore searched by specifying structure=Numeric String. To match all those records with west-bounding-coordinate greater than -114 we use the following query:

          @attr 4=109 @attr 2=5 @attr gils 1=2038 -114

### Present

The present facility is supported in a standard fashion. The requested record syntax is matched against the ones supported by the profile of each record retrieved. If no record syntax is given, SUTRS is the default. The requested element set name, again, is matched against any provided by the relevant record profiles.

### Scan

The attribute combinations provided with the termListAndStartPoint are processed in the same way as operands in a query (see above). Currently, only the term and the globalOccurrences are returned with the termInfo structure.

### Sort

Z39.50 specifies three different types of sort criteria. Of these Zebra supports the attribute specification type in which case the use attribute specifies the "Sort register". Sort registers are created for those fields that are of type "sort" in the default.idx file. The corresponding character mapping file in default.idx specifies the ordinal of each character used in the actual sort.

Z39.50 allows the client to specify sorting on one or more input result sets and one output result set. Zebra supports sorting on one result set only which may or may not be the same as the output result set.

### Close

If a Close PDU is received, the server will respond with a Close PDU with reason=FINISHED, no matter which protocol version was negotiated during initialization. If the protocol version is 3 or more, the server will generate a Close PDU under certain circumstances, including a session timeout (60 minutes by default), and certain kinds of protocol errors. Once a Close PDU has been sent, the protocol association is considered broken, and the transport connection will be closed immediately upon receipt of further data, or following a short timeout.