Function ccl_rpn_query sets attributeSet to Bib-1.
[yaz-moved-to-github.git] / doc / yaz.sgml
1 <!doctype linuxdoc system>
2 <article>
3 <title>YAZ User's Guide and Reference
4 <author><htmlurl url="http://www.indexdata.dk/" name="Index Data">, <tt><htmlurl url="mailto:info@indexdata.dk" name="info@indexdata.dk"></>
5 <date>$Revision: 1.7 $
6 <abstract>
7 This document is the programmer's guide and reference to the YAZ
8 package. YAZ is a compact toolkit that provides access to the
9 Z39.50/SR protocol, as well as a set of higher-level tools for
10 implementing the server and client roles, respectively.
11 The documentation can be used on its own, or as a reference when looking
12 at the example applications provided with the package.
13 </abstract>
14
15 <toc>
16
17 <sect>Introduction
18
19 <p>
20 The <bf/YAZ/ toolkit offers several different levels of access to the
21 Z39.50 and SR protocols. The level that you need to use depends on
22 your requirements, and the role (server or client) that you
23 want to implement.
24
25 The basic level, which is independent of the role, consists of three
26 primary interfaces:
27
28 <itemize>
29 <item><bf/ASN/, which provides a C representation of the Z39.50/SR protocol
30 packages (PDUs).
31 <item><bf/ODR/, which encodes and decodes the packages according to the BER
32 specification.
33 <item><bf/COMSTACK/, which exchanges the encoded packages with a peer process
34 over a network.
35 </itemize>
36
37 The ASN module represents the ASN.1 definition of the
38 SR/Z39.50 protocol. It establishes a set of type and
39 structure definitions, with one structure for each of the top-level
40 PDUs, and one structure or type for each of the contained ASN.1 types.
41 For primitive types, or other types that are defined by the ASN.1
42 standard itself (such as the EXTERNAL type), the C representation is provided
43 by the <bf/ODR/ (Open Data Representation) subsystem.
44
45 <bf/ODR/ is a basic mechanism for representing an
46 ASN.1 type in the C programming language, and for implementing BER
47 encoders and decoders for values of that type. The types defined in
48 the <bf/ASN/
49 module generally have the prefix <tt/Z_/, and a suffix corresponding to
50 the name of the type in the ASN.1
51 specification of the protocol (generally Z39.50-1995). In the case of
52 base types (those originating in the ASN.1 standard itself), the prefix
53 <tt/Odr_/ is sometimes seen. Either way, look for
54 the actual definition in either <tt/proto.h/ (for the types from the
55 protocol), <tt/odr.h/ (for the primitive ASN.1 types, or <tt/odr_use.h/ (for the
56 ASN.1 <it/useful/ types). The <bf/ASN/ library also provides functions (which
57 are, in turn, defined using <bf/ODR/ primitives) for encoding and decoding data
58 values. Their general form is
59
60 <tscreen><verb>
61 int z_xxx(ODR o, Z_xxx **p, int optional, const char *name);
62 </verb></tscreen>
63
64 (note the lower-case &dquot;z&dquot; in the function name)
65
66 <it>
67 NOTE: If you are using the premade definitions of the <bf/ASN/ module, and
68 you are not adding new protocol of your own, the only parts of ODR
69 that you need to worry about are documented in section
70 <ref id="odr-use" name="Using ODR">.
71 </it>
72
73 When you have created a BER-encoded buffer, you can use the <bf/COMSTACK/
74 subsystem to transmit (or receive) data over the network. The <bf/COMSTACK/
75 module provides simple functions for establishing a connection
76 (passively or actively, depending on the role of your application),
77 and for exchanging BER-encoded PDUs over that connection. When you
78 create a connection endpoint, you need to specify what transport to
79 use (OSI or TCP/IP), and which protocol you want to use (SR or
80 Z39.50). For the remainer of the connection's lifetime, you don't have
81 to worry about the underlying transport protocol at all - the <bf/COMSTACK/
82 will ensure that the correct mechanism is used.
83
84 We call the combined interfaces to <bf/ODR/, <bf/ASN/, and <bf/COMSTACK/ the service
85 level API. It's the API that most closely models the Z39.50/SR
86 service/protocol definition, and it provides unlimited access to all
87 fields and facilities of the protocol definitions.
88
89 The reason that the <bf/YAZ/ service-level API is a conglomerate of the
90 APIs from three different submodules is twofold. First, we wanted to allow the
91 user a choice of different options for each major task. For instance,
92 if you don't like the protocol API provided by <bf/ODR//<bf/ASN/, you
93 can use SNACC or BERUtils instead, and still have the benefits of the
94 transparent transport approach of the <bf/COMSTACK/ module. Secondly,
95 we realise that you may have to fit the toolkit into an existing
96 event-processing structure, in a way that
97 is incompatible with the <bf/COMSTACK/ interface or some other part of <bf/YAZ/.
98
99 <sect>Compilation and Installation
100
101 <p>
102 The latest version of the software will generally be found at
103
104 <tscreen><verb>
105 <htmlurl url="http://ftp.indexdata.dk/pub/yaz/" name="http://ftp.indexdata.dk/pub/yaz/">
106 </verb></tscreen>
107
108 We have tried our best to keep the software portable, and on many
109 platforms, you should be able to compile everything with little or no changes.
110 So far, the software has been ported
111 to the following platforms with little or no difficulties.
112
113 <itemize>
114 <item>Unix systems
115 <itemize>
116 <item>HP/UX
117 <item>SunOS/Solaris
118 <item>DEC Unix
119 <item>Linux
120 <item>IBM AIX
121 <item>Data General DG/UX (with some CFLAGS tinkering)
122 <item>SGI/IRIX
123 <item>DDE Supermax
124 </itemize>
125 <item>Non-unix systems
126 <itemize>
127 <item>Apple Macintosh (using the Codewarrior programming environment and the
128 GUSI socket libraries)
129 <item>MS Windows 95/NT (Win32)
130 <item>IBM AS/400
131 </itemize>
132 </itemize>
133
134 If you move the software to other platforms, we'd be grateful if you'd
135 let us know about it. If you run into difficulties, we will try to help if we
136 can, and if you solve the problems, we would be happy to
137 include your fixes in the next release. So far, we have mostly avoided
138 &num;ifdefs for individual platforms, and we'd like to keep it that
139 way as far as it makes sense.
140
141 We maintain a mailing-list for the purpose of announcing new releases and
142 bug-fixes, as well as general discussion. Subscribe by sending mail to
143 <tt/yaz-request@indexdata.dk/. General questions and problems can be
144 directed at <tt/yaz-help@indexdata.dk/, or the address given at the top
145 of this document.
146
147 <sect1>UNIX
148
149 <p>
150 Note that if your system doesn't have a native ANSI C compiler, you may
151 have to acquire one separately. We recommend gcc.
152
153 For UNIX we use GNU configure to create Makefiles for YAZ.
154 Generally it should be sufficient to run configure without options:
155
156 <tscreen><verb>
157 ./configure
158 </verb></tscreen>
159
160 The configure script attempts to use use the C compiler specified by
161 the <tt/CC/ environment variable. If not set, GNU C will be used
162 if it is available. The <tt/CFLAGS/ environment variable holds options
163 to be passed to the C compiler. If you're using Bourne-compatible shell
164 you may pass something like this to use a particular C compiler with
165 optimization enabled:
166 <tscreen><verb>
167   CC=/opt/ccs/bin/cc CFLAGS=-O ./configure
168 </verb></tscreen>
169
170 To customize <bf/YAZ/ the configure script also accepts a set of options.
171 The most important are:
172
173 <descrip>
174 <tag><tt>-</tt><tt>-prefix </tt>path</tag> Specifies installation prefix. This is
175 only needed if you run <tt>make install</tt> later to perform a
176 "system" installation. The prefix is <tt>/usr/local</tt> if not
177 specified.
178
179 <tag><tt>-</tt><tt>-enable-comp </tt></tag> YAZ will be built using
180 the ASN.1 compiler for YAZ (default). If you wish to use the
181 old decoders (in sub directory asn) use <tt>--disable-comp</tt> instead.
182
183 <tag><tt>-</tt><tt>-enable-threads</tt></tag> YAZ will be built using
184 POSIX threads. Specifically, <tt>_REENTRANT</tt> will be defined
185 during compilation.
186 </descrip>
187
188 When configured, build the software by typing:
189 <tscreen><verb>
190   make
191 </verb></tscreen>
192
193 The following files are generated by the make process:
194 <descrip>
195 <tag><tt>lib/libyaz.a</tt></tag> The <bf/YAZ/ programmers' library.
196
197 <tag><tt>ztest/yaz-ztest</tt></tag> A test Z39.50 server.
198
199 <tag><tt>client/yaz-client</tt></tag> A command mode Z39.50 client.
200
201 <tag><tt>yaz-config</tt></tag> A Bourne-shell script that holds build
202 settings for <bf/YAZ/.
203
204 <tag><tt>yaz-comp</tt></tag> The ASN.1 compiler for YAZ. Requires the
205 Tcl Shell, tclsh, in current path to work.
206
207 </descrip>
208
209 If you wish to install <bf/YAZ/ in system directories such as /usr/local/bin,
210 /usr/local/lib) you can type:
211
212 <tscreen><verb>
213   make install
214 </verb></tscreen>
215
216 You probably need to have root access in order to perform this.
217 You must specify the <tt>--prefix</tt> option for configure if you
218 going to install in anything but /usr/local/.
219
220 If you wish to perform an un-installation of YAZ you use:
221
222 <tscreen><verb>
223   make uninstall
224 </verb></tscreen>
225
226 This will only work if you haven't reconfigured YAZ (and therefore
227 changed installation prefix). Note that uninstall will not
228 remove directories created by make install, e.g.
229 <tt>/usr/local/include/yaz</tt>.
230
231 <sect1>WIN32
232
233 <p>
234 <bf/YAZ/ is shipped with "makefiles" for the NMAKE tool that comes
235 with Visual C++.
236
237 Start an MS-DOS prompt and switch the sub directory <tt>WIN</tt> where
238 the file <tt>makefile</tt> is located. Customize the installation
239 by editing the <tt>makefile</tt> file (for example by using notepad).
240
241 The following summarises the most important settings in that file:
242
243 <descrip>
244 <tag><tt>NEW_Z3950</tt></tag> If 1, the auto-generated decoder/encoders
245 for Z39.50 as written by the ASN.1 compiler will be used. If 0, the old
246 decoders for Z39.50 will be used. Note, when 1, the setting TCL should
247 point to the Tcl shell on your system.
248 <tag><tt>DEBUG</tt></tag> If set to 1, the software is
249 compiled with debugging libraries. If set to 0, the software
250 is compiled with release (non-debugging) libraries.
251 </descrip>
252
253 When satisfied with the settings in the makefile type
254 <tscreen><verb>
255 nmake
256 </verb></tscreen>
257
258 The following is generated upon successful compilation:
259 <descrip>
260 <tag><tt>bin/yaz.dll</tt></tag> A multithreaded DLL with everything
261 except the frontend server library.
262 <tag><tt>lib/yaz.lib</tt></tag> An import library for <tt>yaz.dll</tt>.
263 <tag><tt>lib/server.lib</tt></tag> The frontend server library.
264 <tag><tt>bin/yaz-ztest.exe</tt></tag> A test Z39.50 server.
265 <tag><tt>bin/yaz-client.exe</tt></tag> A command mode Z39.50 client.
266 </descrip>
267
268 <sect>Using the Yaz-client
269
270 <p>
271 yaz-client is a linemode Z39.50 client. It supports a fair amount of the
272 functionality of Z39.50-1995 standard, but some things you need to enable or
273 disable by recompilation. Its primary purpose is to exercise the
274 package, and verify that the protocol works OK.
275
276 It can be started by typing
277 <tscreen><verb>
278   yaz-client [-m &lt;marclog&gt;] [ -a &lt;apdulog&gt;] tcp:&lt;hostname&gt;:&lt;port&gt;[/&lt;database&gt;]
279 </verb></tscreen>
280 at the UNIX prompt, to connect to a Z39.50 server.
281
282 The options are
283 <itemize>
284 <item><bf/-m/ Turns dumping of the raw MARC records on in ISO 2709 format.
285 Marclog is the filename to write to.
286 <item><bf/-a/ Turns dumping of the APDU on. Apdulog is the filename to
287 write to. If apdulog is "-" the APDU is written to the screen.
288 </itemize>
289
290 In order to connect to Index Data's test Z39.50 server on
291 bagel.indexdata.dk, port 210 and with the database name marc, one would
292 have to type
293 <tscreen><verb>
294     yaz-client tcp:bagel.indexdata.dk:210/marc
295 </verb></tscreen>
296 In order to also dump the APDU to the screen you would have to write
297 <tscreen><verb>
298     yaz-client -a - tcp:bagel.indexdata.dk:210/marc
299 </verb></tscreen>
300 Use '?' to get a list of the available commands.
301
302 The commands are (the letters in parenthesis are short names for the commands):
303 <descrip>
304 <tag/open (o)/Opens a connection to a server. The syntax is the same as described above for connecting from the command line.
305 <p>Syntax:
306 <tscreen><verb>
307 open ('tcp'|'osi')':'[&lt;tsel&gt;'/']&lt;host&gt;[':'&lt;port&gt;]
308 </verb></tscreen>
309 <tag/quit (q)/
310 Ends yaz-client
311 <p>Syntax:
312 <tscreen><verb>
313 quit
314 </verb></tscreen>
315 <tag/find (f)/
316 Sends the RPN query to the server.
317 <p>Syntax:
318 <tscreen><verb>
319 find &lt;query&gt;
320 </verb></tscreen>
321 <tag/delete/
322 Deletes a result set on the server.
323 <p>Syntax:
324 <tscreen><verb>
325 delete &lt;setname&gt;
326 </verb></tscreen>
327 <tag/base/
328 Sets the name of the database to search in if it wasn't already set in the
329 connect string. More than one database can be searched in parallel by writing
330 several databases (hosted on the same server) separated by white space.
331 <p>Syntax:
332 <tscreen><verb>
333 base &lt;base-name&gt;
334 </verb></tscreen>
335 <tag/show (s)/
336 Shows a record. If no record number is specified the next record in the result set is shown.
337 <p>Syntax:
338 <tscreen><verb>
339 show &lt;rec#&gt;['+'&lt;#recs&gt;['+'&lt;setname&gt;]]
340 </verb></tscreen>
341 <tag/scan/
342 Scans the database index for a term. The syntax resembles the syntax for <bf/find/.
343 If you want to scan for the word <it/water/ you would write
344 <tscreen><verb>
345 scan water
346 </verb></tscreen>
347 but if you want to scan only in, say the title field, you would write
348 <tscreen><verb>
349 scan @attr 1=4 water
350 </verb></tscreen>
351 <p>Syntax:
352 <tscreen><verb>
353 scan <term>
354 </verb></tscreen>
355 <tag/sort/
356 Sorts a result set. The sort command takes a sequence of sort specifications. A sort
357 specification holds a field (sort criteria) and is followed by flags.
358 If the sort criteria includes = it is assumed that the sort SortKey
359 is of type sortAttributes using Bib-1. The integer before the = is
360 the attribute type and the integer following the = is the attribute
361 value. If no = is in the SortKey it is treated as a sortfield-type
362 of type InternationalString. Flags observed are
363 <itemize>
364     <item><bf/s/ (sort case sensitive)
365     <item><bf/i/ (sort case insensitive), &lt; (ascending), &gt; (descending).
366 </itemize>
367 Eg.:
368 <verb>
369    1=4   i&lt;                  (use is title, insensitive, ascending).
370    Title s&gt;                  (String Title, sensitive, descending).
371 </verb>
372 <p>Syntax:
373 <tscreen><verb>
374 sort &lt;sortkey&gt; &lt;flag&gt; &lt;sortkey&gt; &lt;flag&gt; ...
375 </verb></tscreen>
376 <tag/sort+/
377 Same as <bf/sort/ but stores the sorted result set in a new result set.
378 <p>Syntax:
379 <tscreen><verb>
380 sort+ &lt;sortkey&gt; &lt;flag&gt; &lt;sortkey&gt; &lt;flag&gt; ...
381 </verb></tscreen>
382 <tag/authentication/
383 Sets up a authentication string if a server requires authentication. The authentication string is first
384 sent to the server when the <bf/open/ command is issued.
385 <p>Syntax:
386 <tscreen><verb>
387 authentication &lt;acctstring&gt;
388 </verb></tscreen>
389 <tag/lslb/
390 Sets the limit for when no records should be returned together with the search result.
391 See the <htmlurl url="http://lcweb.loc.gov/z3950/agency/markup/04.html#3.2.2.1.6" name="Z39.50 standard">
392 for more details.
393 <p>Syntax:
394 <tscreen><verb>
395 lslb &lt;largeSetLowerBound&gt;
396 </verb></tscreen>
397 <tag/ssub/
398 Sets the limit for when all records should be returned with the search result.
399 See the <htmlurl url="http://lcweb.loc.gov/z3950/agency/markup/04.html#3.2.2.1.6" name="Z39.50 standard">
400 for more details.
401 <p>Syntax:
402 <tscreen><verb>
403 ssub &lt;smallSetUpperBound&gt;
404 </verb></tscreen>
405 <tag/mspn/
406 Sets the number of records should be returned if the number of records in the
407 result set is between the values of <bf/lslb/ and <bf/ssub/.
408 See the <htmlurl url="http://lcweb.loc.gov/z3950/agency/markup/04.html#3.2.2.1.6" name="Z39.50 standard">
409 for more details.
410 <p>Syntax:
411 <tscreen><verb>
412 mspn &lt;mediumSetPresentNumber&gt;
413 </verb></tscreen>
414 <tag/status/
415 Displays the values of <bf/lslb/, <bf/ssub/ and <bf/mspn/.
416 <p>Syntax:
417 <tscreen><verb>
418 status
419 </verb></tscreen>
420 <tag/setname/
421 Switches named result sets on and off. Default is on.
422 <p>Syntax:
423 <tscreen><verb>
424 setnames
425 </verb></tscreen>
426 <tag/cancel/
427 Sends a trigger resource ctrl cancel to the server.
428 <p>Syntax:
429 <tscreen><verb>
430 cancel
431 </verb></tscreen>
432 <tag/format/
433 Sets the preferred transfer syntax the records should be returned in.
434 yaz-client supports all the record syntaxes that corrently are registered
435 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
436 <p>Syntax:
437 <tscreen><verb>
438 format &lt;recordsyntax&gt;
439 </verb></tscreen>
440 <tag/schema/
441 Sets the preferred schema the records should be returned in.
442 <p>Syntax:
443 <tscreen><verb>schema &lt;schema&gt;
444 </verb></tscreen>
445 <tag/elements/
446 Sets the element set name for the records.
447 <itemize>
448 <item><bf/b/ Brief
449 <item><bf/f/ Full
450 <item>Any other element set name the server may support
451 </itemize>
452 <p>Syntax:
453 <tscreen><verb>
454 elements &lt;elementSetName&gt;
455 </verb></tscreen>
456 <tag/close/
457 Sends a close request.
458 <p>Syntax:
459 <tscreen><verb>close
460 </verb></tscreen>
461 <tag/querytype/
462 Sets the query type. Default is prefix.
463 <itemize>
464 <item><bf/prefix/ RPN query.
465 <item><bf/CCL/ CCL (Common Command Language) query.
466 <item><bf/ CCL2RPN/A CCL variant that is interpreted on the client side
467 which allows you to specify field names. See section <ref id="CCL" name="Common Command Language"> for more details.
468 </itemize>
469 <p>Syntax:
470 <tscreen><verb>
471 querytype &lt;type&gt;
472 </verb></tscreen>
473 <tag/attributeset/
474 Specifies the default attribute set in the query. Default is Bib1
475 (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
476 you can also specify the attribute set directly in the RPN query.
477 <p>Syntax:
478 <tscreen><verb>
479 attributeset &lt;attrset&gt;
480 </verb></tscreen>
481 <tag/refid/
482 Sets a reference id for a request to be send to the server.
483 See the <htmlurl url="http://lcweb.loc.gov/z3950/agency/markup/08.html#3.4" name="Z39.50 standard">
484 for more details.
485 <p>Syntax:
486 <tscreen><verb>
487 refid <id>
488 </verb></tscreen>
489 <tag/itemorder/
490 Sends an itemorder to the server. Only the required fields are implemented.
491 <p>Syntax:
492 <tscreen><verb>
493 itemorder 1|2 &lt;item&gt;
494 </verb></tscreen>
495 <tag/update/
496 Sends an item update to the server. This feature is not fully implemented yet.
497 <p>Syntax:
498 <tscreen><verb>
499 update &lt;item&gt;
500 </verb></tscreen>
501 </descrip>
502 <sect1>Searching with yaz-client
503 <p>
504 The simplest form of a RPM query in yaz-client would be something like
505 <tscreen><verb>
506     f knuth
507 </verb></tscreen>
508 or
509 <tscreen><verb>
510     f "donald knuth"
511 </verb></tscreen>
512 This leaves it up to the server what fields to search but most servers will search
513 in all fields. Some servers does not support this feature though, and require that
514 a search attribute is defined. This would look something like this in yaz-client:
515 <tscreen><verb>
516     f @attr 1=4 computer
517 </verb></tscreen>
518 where we search in the title field. If we want to search in the author field <bf/and/
519 in the title field, and in the title field using right truncation it could look something like this:
520 <tscreen><verb>
521     f @and @attr 1=1003 knuth @attr 1=4 @attr 5=1 computer
522 </verb></tscreen>
523 Finally using a mix of Bib-1 and GILS attributes could look something like this:
524 <tscreen><verb>
525     f @attrset Bib-1 @and @attr GILS 2=2008 Washington @attr 1=21 weather
526 </verb></tscreen>
527 For the full spacifiction of the RPN query language please see the section <ref id="PQF" name="Prefix Query Format">.
528
529 <sect>The ASN Module
530
531 <sect1>Introduction
532
533 <p>
534 The <bf/ASN/ module provides you with a set of C struct definitions for the
535 various PDUs of the protocol, as well as for the complex types
536 appearing within the PDUs. For the primitive data types, the C
537 representation often takes the form of an ordinary C language type,
538 such as <tt/int/. For ASN.1 constructs that have no direct
539 representation in C, such as general octet strings and bit strings,
540 the <bf/ODR/ module (see section <ref id="odr" name="ODR">) provides auxiliary
541 definitions.
542
543 <sect1>Preparing PDUs
544
545 <p>
546 A structure representing a complex ASN.1 type doesn't in itself contain the
547 members of that type. Instead, the structure contains <it/pointers/ to
548 the members of the type. This is necessary, in part, to allow a mechanism for
549 specifying which of the optional structure (SEQUENCE) members are
550 present, and which are not. It follows that you will need to somehow
551 provide space for the individual members of the structure, and
552 set the pointers to refer to the members.
553
554 The conversion routines don't care how you allocate and maintain your
555 C structures - they just follow the pointers that you provide.
556 Depending on the complexity of your application, and your personal
557 taste, there are at least three different approaches that you may take
558 when you allocate the structures.
559
560 <itemize>
561 <item>
562 You can use static or automatic local variables in the function that
563 prepares the PDU. This is a simple approach, and it provides the most
564 efficient form of memory management. While it works well for flat
565 PDUs like the InitReqest, it will generally not be sufficient for say,
566 the generation of an arbitrarily complex RPN query structure.
567 <item>
568 You can individually create the structure and its members using the
569 <tt/malloc/(2) function. If you want to ensure that the data is freed when
570 it is no longer needed, you will have to define a function that
571 individually releases each member of a structure before freeing the
572 structure itself.
573 <item>
574 You can use the <tt/odr_malloc()/ function (see section <ref
575 id="odr-use"
576 name="Using ODR"> for details). When you use <tt/odr_malloc()/, you can release
577 all of the
578 allocated data in a single operation, independent of any pointers and
579 relations between the data. <tt/odr_malloc()/ is based on a
580 &dquot;nibble-memory&dquot;
581 scheme, in which large portions of memory are allocated, and then
582 gradually handed out with each call to <tt/odr_malloc()/. The next time you
583 call <tt/odr_reset()/, all of the memory allocated since the last call is
584 recycled for future use (actually, it is placed on a free-list).
585 <item>
586 You can combine all of the methods described here. This will often be
587 the most practical approach. For instance, you might use <tt/odr_malloc()/ to
588 allocate an entire structure and some of its elements, while you leave
589 other elements pointing to global or per-session default variables.
590 </itemize>
591
592 The <bf/ASN/ module provides an important aid in creating new PDUs. For
593 each of the PDU types (say, <tt/Z_InitRequest/), a function is provided
594 that allocates and initializes an instance of that PDU type for you.
595 In the case of the InitRequest, the function is simply named
596 <tt/zget_InitRequest()/, and it sets up reasonable default value for all of
597 the mandatory members. The optional members are generally initialized to null
598 pointers. This last aspect is very important: it ensures that if the
599 PDU definitions are extended after you finish your implementation
600 (to accommodate
601 new versions of the protocol, say), you won't get into trouble with
602 uninitialized pointers in your structures. The functions use
603 <tt/odr_malloc()/ to
604 allocate the PDUs and its members, so you can free everything again with a
605 single call to <tt/odr_reset()/. We strongly recommend that you use the
606 <tt/zget_*/
607 functions whenever you are preparing a PDU (in a C++ API, the
608 <tt/zget_/
609 functions would probably be promoted to constructors for the
610 individual types).
611
612 The prototype for the individual PDU types generally look like this:
613
614 <tscreen><verb>
615 Z_<type> *zget_<type>(ODR o);
616 </verb></tscreen>
617
618 eg.:
619
620 <tscreen><verb>
621 Z_InitRequest *zget_InitRequest(ODR o);
622 </verb></tscreen>
623
624 The <bf/ODR/ handle should generally be your encoding stream, but it
625 needn't be.
626
627 As well as the individual PDU functions, a function <tt/zget_APDU()/ is
628 provided, which allocates a toplevel Z-APDU of the type requested:
629
630 <tscreen><verb>
631 Z_APDU *zget_APDU(ODR o, int which);
632 </verb></tscreen>
633
634 The <tt/which/ parameter is (of course) the discriminator belonging to the
635 <tt/Z_APDU/ CHOICE type. All of the interface described here is provided by
636 the <bf/ASN/ module, and you access it through the <tt/proto.h/ header file.
637
638 <sect1>Object Identifiers<label id="oid">
639
640 <p>
641 When you refer to object identifiers in your application, you need to
642 be aware that SR and Z39.50 use two different set of OIDs to refer to
643 the same objects. To handle this easily, <bf/YAZ/ provides a utility module
644 to <bf/ASN/ which provides an internal representation of the OIDs used in
645 both protocols. Each oid is described by a structure:
646
647 <tscreen><verb>
648 typedef struct oident
649 {
650     enum oid_proto proto;
651     enum oid_class class;
652     enum oid_value value;
653     int oidsuffix[OID_SIZE];
654     char *desc;
655 } oident;
656 </verb></tscreen>
657
658 The <tt/proto/ field can be set to either <tt/PROTO_SR/ or
659 <tt/PROTO_Z3950/. The <tt/class/ might be, say, <tt/CLASS_RECSYN/, and the
660 <tt/value/ might be <tt/VAL_USMARC/ for the USMARC record format. Functions
661
662 <tscreen><verb>
663 int *oid_ent_to_oid(struct oident *ent, int *dst);
664 struct oident *oid_getentbyoid(int *o);
665 </verb></tscreen>
666
667 are provided to map between object identifiers and database entries.
668 If you store a member of the <tt/oid_proto/ type in your association
669 state information, it's a simple matter, at runtime, to generate the
670 correct OID when you need it. For decoding, you can simply ignore the
671 proto field, or if you're strict, you can verify that your peer is
672 using the OID family from the correct protocol. The <tt/desc/ field is
673 a short, human-readable name for the PDU, useful mainly for diagnostic
674 output.
675
676 <it>
677 NOTE: The old function oid_getoidbyent still exists but is
678 not thread safe. Use oid_ent_to_oid instead and pass an array of
679 size OID_SIZE.
680 </it>
681
682 <it>
683 NOTE: Plans are underway to merge the two protocols into a single
684 definition, with one set of object identifiers. When this happens, the
685 oid module will no longer be required to support protocol
686 independence, but it should still be useful as a simple OID database.
687 </it>
688
689 <sect1>EXTERNAL Data
690
691 <p>
692 In order to achieve extensibility and adaptability to different
693 application domains, the new version of the protocol defines many
694 structures outside of the main ASN.1 specification, referencing them
695 through ASN.1 EXTERNAL constructs. To simplify the construction and access
696 to the externally referenced data, the <bf/ASN/ module defines a
697 specialized version of the EXTERNAL construct, called <tt/Z_External/.
698 It is defined thus:
699
700 <tscreen><verb>
701 typedef struct Z_External
702 {
703     Odr_oid *direct_reference;
704     int *indirect_reference;
705     char *descriptor;
706     enum
707     {
708         /* Generic types */
709         Z_External_single = 0,
710         Z_External_octet,
711         Z_External_arbitrary,
712
713         /* Specific types */
714         Z_External_SUTRS,
715         Z_External_explainRecord,
716         Z_External_resourceReport1,
717         Z_External_resourceReport2
718
719         ...
720
721     } which;
722     union
723     {
724         /* Generic types */
725         Odr_any *single_ASN1_type;
726         Odr_oct *octet_aligned;
727         Odr_bitmask *arbitrary;
728
729         /* Specific types */
730         Z_SUTRS *sutrs;
731         Z_ExplainRecord *explainRecord;
732         Z_ResourceReport1 *resourceReport1;
733         Z_ResourceReport2 *resourceReport2;
734
735         ...
736
737     } u;
738 } Z_External;
739 </verb></tscreen>
740
741 When decoding, the <bf/ASN/ module will attempt to determine which
742 syntax describes the data by looking at the reference fields
743 (currently only the direct-reference). For ASN.1 structured data, you
744 need only consult the <tt/which/ field to determine the type of data.
745 You can the access  the data directly through the union. When
746 constructing data for encoding, you set the union pointer to point to
747 the data, and set the <tt/which/ field accordingly. Remember also to
748 set the direct (or indirect) reference to the correct OID for the data
749 type. For non-ASN.1 data such as MARC records, use the
750 <tt/octet_aligned/ arm of the union.
751
752 Some servers return ASN.1 structured data values (eg. database
753 records) as BER-encoded records placed in the <tt/octet-aligned/
754 branch of the EXTERNAL CHOICE. The ASN-module will <it/not/
755 automatically decode these records. To help you decode the records in
756 the application, the function
757
758 <tscreen><verb>
759 Z_ext_typeent *z_ext_gettypebyref(oid_value ref);
760 </verb></tscreen>
761
762 Can be used to retrieve information about the known, external data
763 types. The function return a pointer to a static area, or NULL, if no
764 match for the given direct reference is found. The <tt/Z_ext_typeent/
765 is defined as:
766
767 <tscreen><verb>
768 typedef struct Z_ext_typeent
769 {
770     oid_value dref;    /* the direct-reference OID value. */
771     int what;          /* discriminator value for the external CHOICE */
772     Odr_fun fun;       /* decoder function */
773 } Z_ext_typeent;
774 </verb></tscreen>
775
776 The <tt/what/ member contains the Z_External union discriminator value
777 for the given type: For the SUTRS record syntax, the value would be
778 <tt/Z_External_sutrs/. The <tt/fun/ member contains a pointer to the
779 function which encodes/decodes the given type. Again, for the SUTRS
780 record syntax, the value of <tt/fun/ would be <tt/z_SUTRS/ (a function
781 pointer).
782
783 If you receive an EXTERNAL which contains an octet-string value that
784 you suspect of being an ASN.1-structured data value, you can use
785 <tt/z_ext_gettypebyref/ to look for the provided direct-reference. If
786 the return value is different from NULL, you can use the provided
787 function to decode the BER string (see section <ref id="odr-use"
788 name="Using ODR">).
789
790 If you want to <it/send/ EXTERNALs containing ASN.1-structured values
791 in the occtet-aligned branch of the CHOICE, this is possible too.
792 However, on the encoding phase, it requires a somewhat involved
793 juggling around of the various buffers involved.
794
795 If you need to add new, externally defined data types, you must update
796 the struct above, in the source file <tt/prt-ext.h/, as well as the
797 encoder/decoder in the file <tt/prt-ext.c/. When changing the latter,
798 remember to update both the <tt/arm/ arrary and the list <tt/type_table/,
799 which drives the CHOICE biasing that is necessary to tell the
800 different, structured types apart on decoding.
801
802 <it>
803 NOTE: Eventually, the EXTERNAL processing will most likely
804 automatically insert the correct OIDs or indirect-refs. First,
805 however, we need to determine how application-context management
806 (specifically the presentation-context-list) should fit into the
807 various modules.
808 </it>
809
810 <sect1>PDU Contents Table
811
812 <p>
813 We include, for reference, a listing of the fields of each top-level
814 PDU, as well as their default settings.
815
816 <verb>
817 Z_InitRequest
818 -------------
819 Field                        Type                Default value
820
821 referenceId                  Z_ReferenceId       NULL
822 protocolVersion              Odr_bitmask         Empty bitmask
823 options                      Odr_bitmask         Empty bitmask
824 preferredMessageSize         int                 30*1024
825 maximumRecordSize            int                 30*1024
826 idAuthentication             Z_IdAuthentication  NULL
827 implementationId             char*               "YAZ (id=81)"
828 implementationName           char*               "Index Data/YAZ"
829 implementationVersion        char*               YAZ_VERSION
830 userInformationField         Z_UserInformation   NULL
831 otherInfo                    Z_OtherInformation  NULL
832
833 Z_InitResponse
834 --------------
835 Field                        Type                Default value
836
837 referenceId                  Z_ReferenceId       NULL
838 protocolVersion              Odr_bitmask         Empty bitmask
839 options                      Odr_bitmask         Empty bitmask
840 preferredMessageSize         int                 30*1024
841 maximumRecordSize            int                 30*1024
842 result                       bool_t              TRUE
843 implementationId             char*               "YAZ (id=81)"
844 implementationName           char*               "Index Data/YAZ"
845 implementationVersion        char*               YAZ_VERSION
846 userInformationField         Z_UserInformat..    NULL
847 otherInfo                    Z_OtherInformation  NULL
848
849 Z_SearchRequest
850 ---------------
851 Field                        Type                Default value
852
853 referenceId                  Z_ReferenceId       NULL
854 smallSetUpperBound           int                 0
855 largeSetLowerBound           int                 1
856 mediumSetPresentNumber       int                 0
857 replaceIndicator             bool_t              TRUE
858 resultSetName                char*               "default"
859 num_databaseNames            int                 0
860 databaseNames                char**              NULL
861 smallSetElementSetNames      Z_ElementSetNames   NULL
862 mediumSetElementSetNames     Z_ElementSetNames   NULL
863 preferredRecordSyntax        Odr_oid             NULL
864 query                        Z_Query             NULL
865 additionalSearchInfo         Z_OtherInformation  NULL
866 otherInfo                    Z_OtherInformation  NULL
867
868 Z_SearchResponse
869 ----------------
870 Field                        Type                Default value
871
872 referenceId                  Z_ReferenceId       NULL
873 resultCount                  int                 0
874 numberOfRecordsReturned      int                 0
875 nextResultSetPosition        int                 0
876 searchStatus                 bool_t              TRUE
877 resultSetStatus              int                 NULL
878 presentStatus                int                 NULL
879 records                      Z_Records           NULL
880 additionalSearchInfo         Z_OtherInformation  NULL
881 otherInfo                    Z_OtherInformation  NULL
882
883 Z_PresentRequest
884 ----------------
885 Field                        Type                Default value
886
887 referenceId                  Z_ReferenceId       NULL
888 resultSetId                  char*               "default"
889 resultSetStartPoint          int                 1
890 numberOfRecordsRequested     int                 10
891 num_ranges                   int                 0
892 additionalRanges             Z_Range             NULL
893 recordComposition            Z_RecordComposition NULL
894 preferredRecordSyntax        Odr_oid             NULL
895 maxSegmentCount              int                 NULL
896 maxRecordSize                int                 NULL
897 maxSegmentSize               int                 NULL
898 otherInfo                    Z_OtherInformation  NULL
899
900 Z_PresentResponse
901 -----------------
902 Field                        Type                Default value
903
904 referenceId                  Z_ReferenceId       NULL
905 numberOfRecordsReturned      int                 0
906 nextResultSetPosition        int                 0
907 presentStatus                int                 Z_PRES_SUCCESS
908 records                      Z_Records           NULL
909 otherInfo                    Z_OtherInformation  NULL
910
911 Z_DeleteResultSetRequest
912 ------------------------
913 Field                        Type                Default value
914
915 referenceId                  Z_ReferenceId       NULL
916 deleteFunction               int                 Z_DeleteRequest_list
917 num_ids                      int                 0
918 resultSetList                char**              NULL
919 otherInfo                    Z_OtherInformation  NULL
920
921 Z_DeleteResultSetResponse
922 -------------------------
923 Field                        Type                Default value
924
925 referenceId                  Z_ReferenceId       NULL
926 deleteOperationStatus        int                 Z_DeleteStatus_success
927 num_statuses                 int                 0
928 deleteListStatuses           Z_ListStatus**      NULL
929 numberNotDeleted             int                 NULL
930 num_bulkStatuses             int                 0
931 bulkStatuses                 Z_ListStatus        NULL
932 deleteMessage                char*               NULL
933 otherInfo                    Z_OtherInformation  NULL
934
935 Z_ScanRequest
936 -------------
937 Field                        Type                Default value
938
939 referenceId                  Z_ReferenceId       NULL
940 num_databaseNames            int                 0
941 databaseNames                char**              NULL
942 attributeSet                 Odr_oid             NULL
943 termListAndStartPoint        Z_AttributesPlus... NULL
944 stepSize                     int                 NULL
945 numberOfTermsRequested       int                 20
946 preferredPositionInResponse  int                 NULL
947 otherInfo                    Z_OtherInformation  NULL
948
949 Z_ScanResponse
950 --------------
951 Field                        Type                Default value
952
953 referenceId                  Z_ReferenceId       NULL
954 stepSize                     int                 NULL
955 scanStatus                   int                 Z_Scan_success
956 numberOfEntriesReturned      int                 0
957 positionOfTerm               int                 NULL
958 entries                      Z_ListEntris        NULL
959 attributeSet                 Odr_oid             NULL
960 otherInfo                    Z_OtherInformation  NULL
961
962 Z_TriggerResourceControlRequest
963 -------------------------------
964 Field                        Type                Default value
965
966 referenceId                  Z_ReferenceId       NULL
967 requestedAction              int                 Z_TriggerResourceCtrl_resou..
968 prefResourceReportFormat     Odr_oid             NULL
969 resultSetWanted              bool_t              NULL
970 otherInfo                    Z_OtherInformation  NULL
971
972 Z_ResourceControlRequest
973 ------------------------
974 Field                        Type                Default value
975
976 referenceId                  Z_ReferenceId       NULL
977 suspendedFlag                bool_t              NULL
978 resourceReport               Z_External          NULL
979 partialResultsAvailable      int                 NULL
980 responseRequired             bool_t              FALSE
981 triggeredRequestFlag         bool_t              NULL
982 otherInfo                    Z_OtherInformation  NULL
983
984 Z_ResourceControlResponse
985 -------------------------
986 Field                        Type                Default value
987
988 referenceId                  Z_ReferenceId       NULL
989 continueFlag                 bool_t              TRUE
990 resultSetWanted              bool_t              NULL
991 otherInfo                    Z_OtherInformation  NULL
992
993 Z_AccessControlRequest
994 ----------------------
995 Field                        Type                Default value
996
997 referenceId                  Z_ReferenceId       NULL
998 which                        enum                Z_AccessRequest_simpleForm;
999 u                            union               NULL
1000 otherInfo                    Z_OtherInformation  NULL
1001
1002 Z_AccessControlResponse
1003 -----------------------
1004 Field                        Type                Default value
1005
1006 referenceId                  Z_ReferenceId       NULL
1007 which                        enum                Z_AccessResponse_simpleForm
1008 u                            union               NULL
1009 diagnostic                   Z_DiagRec           NULL
1010 otherInfo                    Z_OtherInformation  NULL
1011
1012 Z_Segment
1013 ---------
1014 Field                        Type                Default value
1015
1016 referenceId                  Z_ReferenceId       NULL
1017 numberOfRecordsReturned      int                 value=0
1018 num_segmentRecords           int                 0
1019 segmentRecords               Z_NamePlusRecord    NULL
1020 otherInfo                    Z_OtherInformation  NULL
1021
1022 Z_Close
1023 -------
1024 Field                        Type                Default value
1025
1026 referenceId                  Z_ReferenceId       NULL
1027 closeReason                  int                 Z_Close_finished
1028 diagnosticInformation        char*               NULL
1029 resourceReportFormat         Odr_oid             NULL
1030 resourceFormat               Z_External          NULL
1031 otherInfo                    Z_OtherInformation  NULL
1032 </verb>
1033
1034 <sect>Supporting Tools
1035
1036 <p>
1037 In support of the service API - primarily the ASN module, which
1038 provides the programmatic interface to the Z39.50 APDUs, YAZ contains
1039 a collection of tools that support the development of applications.
1040
1041 <sect1>Query Syntax Parsers
1042
1043 <p>
1044 Since the type-1 (RPN) query structure has no direct, useful string
1045 representation, every origin application needs to provide some form of
1046 mapping from a local query notation or representation to a
1047 <tt/Z_RPNQuery/ structure. Some programmers will prefer to construct
1048 the query manually, perhaps using <tt/odr_malloc()/ to simplify memory
1049 management. The YAZ distribution includes two separate,
1050 query-generating tools that may be of use to you.
1051
1052 <sect2>Prefix Query Format<label id="PQF">
1053
1054 <p>
1055 Since RPN or reverse polish notation is really just a fancy way of
1056 describing a suffix notation format (operator follows operands), it
1057 would seem that the confusion is total when we now introduce a prefix
1058 notation for RPN. The reason is one of simple laziness - it's somewhat
1059 simpler to interpret a prefix format, and this utility was designed
1060 for maximum simplicity, to provide a baseline representation for use
1061 in simple test applications and scripting environments (like Tcl). The
1062 demonstration client included with YAZ uses the PQF.
1063
1064 The PQF is defined by the pquery module in the YAZ library. The
1065 <tt/pquery.h/ file provides the declaration of the functions
1066
1067 <tscreen><verb>
1068 Z_RPNQuery *p_query_rpn (ODR o, oid_proto proto, const char *qbuf);
1069
1070 Z_AttributesPlusTerm *p_query_scan (ODR o, oid_proto proto,
1071       Odr_oid **attributeSetP, const char *qbuf);
1072
1073 int p_query_attset (const char *arg);
1074 </verb></tscreen>
1075
1076 The function <tt/p_query_rpn()/ takes as arguments an <bf/ODR/ stream
1077 (see section <ref id="odr" name="The ODR Module">) to provide a memory
1078 source (the structure created is released on the next call to
1079 <tt/odr_reset()/ on the stream/), a protocol identifier (one of the
1080 constants <tt/PROTO_Z3950/ and <tt/PROTO_SR/), an attribute set
1081 reference, and finally a null-terminated string holding the query
1082 string.
1083
1084 If the parse went well, <tt/p_query_rpn()/ returns a pointer to a
1085 <tt/Z_RPNQuery/ structure which can be placed directly into a
1086 <tt/Z_SearchRequest/.
1087
1088 The <tt/p_query_attset/ specifies which attribute set to use if
1089 the query doesn't specify one by the <tt/@attrset/ operator. The
1090 <tt/p_query_attset/ returns 0 if the argument is a valid attribute
1091 set specifier; otherwise the function returns -1.
1092
1093 The grammar of the PQF is as follows:
1094
1095 <tscreen><verb>
1096 Query ::= &lsqb; AttSet &rsqb; QueryStruct.
1097
1098 AttSet ::= string.
1099
1100 QueryStruct ::= { Attribute } Simple | Complex.
1101
1102 Attribute ::= '@attr' AttributeType '=' AttributeValue.
1103
1104 AttributeType ::= integer.
1105
1106 AttributeValue ::= integer.
1107
1108 Complex ::= Operator QueryStruct QueryStruct.
1109
1110 Operator ::= '@and' | '@or' | '@not' | '@prox' Proximity.
1111
1112 Simple ::= ResultSet | Term.
1113
1114 ResultSet ::= '@set' string.
1115
1116 Term ::= string | '"' string '"'.
1117
1118 Proximity ::= Exclusion Distance Ordered Relation WhichCode UnitCode.
1119
1120 Exclusion ::= '1' | '0' | 'void'.
1121
1122 Distance ::= integer.
1123
1124 Ordered ::= '1' | '0'.
1125
1126 Relation ::= integer.
1127
1128 WhichCode ::= 'known' | 'private' | integer.
1129
1130 UnitCode ::= integer.
1131 </verb></tscreen>
1132
1133 You will note that the syntax above is a fairly faithful
1134 representation of RPN, except for the <tt/Attibute/, which has been
1135 moved a step away from the term, allowing you to associate one or more
1136 attributes with an entire query structure. The parser will
1137 automatically apply the given attributes to each term as required.
1138
1139 The following are all examples of valid queries in the PQF.
1140
1141 <tscreen><verb>
1142 dylan
1143
1144 "bob dylan"
1145
1146 @or "dylan" "zimmerman"
1147
1148 @set Result-1
1149
1150 @or @and bob dylan @set Result-1
1151
1152 @attr 4=1 @and @attr 1=1 "bob dylan" @attr 1=4 "slow train coming"
1153
1154 @attr 4=1 @attr 1=4 "self portrait"
1155
1156 @prox 0 3 1 2 k 2 dylan zimmerman
1157 </verb></tscreen>
1158
1159 <sect2>Common Command Language<label id="CCL">
1160
1161 <p>
1162 Not all users enjoy typing in prefix query structures and numerical
1163 attribute values, even in a minimalistic test client. In the library
1164 world, the more intuitive Common Command Language (or ISO 8777) has
1165 enjoyed some popularity - especially before the widespread
1166 availability of graphical interfaces. It is still useful in
1167 applications where you for some reason or other need to provide a
1168 symbolic language for expressing boolean query structures.
1169
1170 The EUROPAGATE research project working under the Libraries programme
1171 of the European Commission's DG XIII has, amongst other useful tools,
1172 implemented a general-purpose CCL parser which produces an output
1173 structure that can be trivially converted to the internal RPN
1174 representation of YAZ (The <tt/Z_RPNQuery/ structure). Since the CCL
1175 utility - along with the rest of the software produced by EUROPAGATE -
1176 is made freely available on a liberal license, it is included as a
1177 supplement to YAZ.
1178
1179 <sect3>CCL Syntax
1180 <p>
1181 The CCL parser obeys the following grammar for the FIND argument.
1182 The syntax is annotated by in the lines prefixed by <tt/--/.
1183
1184 <tscreen><verb>
1185 CCL-Find ::= CCL-Find Op Elements
1186            | Elements.
1187
1188 Op ::= "and" | "or" | "not"
1189 -- The above means that Elements are separated by boolean operators.
1190
1191 Elements ::= '(' CCL-Find ')'
1192            | Set
1193            | Terms
1194            | Qualifiers Relation Terms
1195            | Qualifiers Relation '(' CCL-Find ')'
1196            | Qualifiers '=' string '-' string
1197 -- Elements is either a recursive definition, a result set reference, a
1198 -- list of terms, qualifiers followed by terms, qualifiers followed
1199 -- by a recursive definition or qualifiers in a range (lower - upper).
1200
1201 Set ::= 'set' = string
1202 -- Reference to a result set
1203
1204 Terms ::= Terms Prox Term
1205         | Term
1206 -- Proximity of terms.
1207
1208 Term ::= Term string
1209        | string
1210 -- This basically means that a term may include a blank
1211
1212 Qualifiers ::= Qualifiers ',' string
1213              | string
1214 -- Qualifiers is a list of strings separated by comma
1215
1216 Relation ::= '=' | '>=' | '<=' | '<>' | '>' | '<'
1217 -- Relational operators. This really doesn't follow the ISO8777
1218 -- standard.
1219
1220 Prox ::= '%' | '!'
1221 -- Proximity operator
1222
1223 </verb></tscreen>
1224
1225 The following queries are all valid:
1226
1227 <tscreen><verb>
1228 dylan
1229
1230 "bob dylan"
1231
1232 dylan or zimmerman
1233
1234 set=1
1235
1236 (dylan and bob) or set=1
1237
1238 </verb></tscreen>
1239 Assuming that the qualifiers <tt/ti/, <tt/au/ and <tt/date/
1240 are defined we may use:
1241 <tscreen><verb>
1242 ti=self portrait
1243
1244 au=(bob dylan and slow train coming)
1245
1246 date>1980 and (ti=((self portrait)))
1247 </verb></tscreen>
1248
1249 <sect3>CCL Qualifiers
1250 <p>
1251
1252 Qualifiers are used to direct the search to a particular searchable
1253 index, such as title (ti) and author indexes (au). The CCL standard
1254 itself doesn't specify a particular set of qualifiers, but it does
1255 suggest a few short-hand notations. You can customize the CCL parser
1256 to support a particular set of qualifiers to relect the current target
1257 profile. Traditionally, a qualifier would map to a particular
1258 use-attribute within the BIB-1 attribute set. However, you could also
1259 define qualifiers that would set, for example, the
1260 structure-attribute.
1261
1262 Consider a scenario where the target support ranked searches in the
1263 title-index. In this case, the user could specify
1264 <tscreen><verb>
1265 ti,ranked=knuth computer
1266 </verb></tscreen>
1267 and the <tt/ranked/ would map to structure=free-form-text
1268 (4=105) and the <tt/ti/ would map to title (1=4).
1269
1270 A "profile" with a set predefined CCL qualifiers can be read from a
1271 file. The YAZ client reads its CCL qualifiers from a file named
1272 <tt/default.bib/. Each line in the file has the form:
1273
1274 <it/qualifier-name/    <it/type/=<it/val/ <it/type/=<it/val/ ...
1275
1276 where <it/qualifier-name/ is the name of the qualifier to be used
1277 (eg. <tt/ti/), <it/type/ is a BIB-1 category type and <it/val/ is the
1278 corresponding BIB-1 attribute value. The <it/type/ can be either
1279 numeric or it may be either <tt/u/ (use), <tt/r/ (relation), <tt/p/
1280 (position), <tt/s/ (structure), <tt/t/ (truncation) or <tt/c/
1281 (completeness). The <it/qualifier-name/ <tt/term/ has a special
1282 meaning. The types and values for this definition is used when <it/no/
1283 qualifier is present.
1284
1285 Consider the following definition:
1286 <tscreen><verb>
1287 ti       u=4 s=1
1288 au       u=1 s=1
1289 term     s=105
1290 </verb></tscreen>
1291 Two qualifiers are defined, <tt/ti/ and <tt/au/. They both set the
1292 structure-attribute to phrase (1). <tt/ti/ sets the use-attribute to
1293 4. <tt/au/ sets the use-attribute to 1. When no qualifiers are used
1294 in the query the structure-attribute is set to free-form-text (105).
1295
1296 <sect3>CCL API
1297 <p>
1298
1299 All public definitions can be found in the header file <tt/ccl.h/.
1300 A profile identifier is of type <tt/CCL_bibset/. A profile must be
1301 created with the call to the function <tt/ccl_qual_mk/ which returns
1302 a profile handle of type <tt/CCL_bibset/.
1303
1304 To read a file containing qualifier definitions the function
1305 <tt/ccl_qual_file/ may be convenient. This function takes an already
1306 opened <tt/FILE/ handle pointer as argument along with a
1307 <tt/CCL_bibset/ handle.
1308
1309 To parse a simple string with a FIND query use the function
1310 <tscreen><verb>
1311 struct ccl_rpn_node *ccl_find_str (CCL_bibset bibset, const char *str,
1312                                    int *error, int *pos);
1313 </verb></tscreen>
1314 which takes the CCL profile (<tt/bibset/) and query (<tt/str/) as
1315 input. Upon successful completion the RPN tree is returned. If an
1316 error eccur, such as a syntax error, the integer pointed to by
1317 <tt/error/ holds the error code and <tt/pos/ holds the offset inside
1318 query string in which the parsing failed.
1319
1320 An english representation of the error may be obtained by calling
1321 the <tt/ccl_err_msg/ function. The error codes are listed in
1322 <tt/ccl.h/.
1323
1324 To convert the CCL RPN tree (type <tt/struct ccl_rpn_node */) to the
1325 Z_RPNQuery of YAZ the function <tt/ccl_rpn_query/ must be used. This
1326 function which is part of YAZ is implemented in <tt/yaz-ccl.c/.
1327 After calling this function the CCL RPN tree is probably no longer
1328 needed. The <tt/ccl_rpn_delete/ destroys the CCL RPN tree.
1329
1330 A CCL profile may be destroyed by calling the <tt/ccl_qual_rm/
1331 function.
1332
1333 The token names for the CCL operators may be changed by setting the
1334 globals (all type <tt/char */) <tt/ccl_token_and/, <tt/ccl_token_or/,
1335 <tt/ccl_token_not/ and <tt/ccl_token_set/.
1336 An operator may have aliases, i.e. there may be more than one name for
1337 the operator. To do this, separate each alias with a space character.
1338
1339 <sect1>Object Identifiers
1340
1341 <p>
1342 The basic YAZ representation of an OID is an array of integers,
1343 terminated with the value -1. The <bf/ODR/ module provides two
1344 utility-functions to create and copy this type of data elements:
1345
1346 <tscreen><verb>
1347 Odr_oid *odr_getoidbystr(ODR o, char *str);
1348 </verb></tscreen>
1349
1350 Creates an OID based on a string-based representation using dots (.)
1351 to separate elements in the OID.
1352
1353 <tscreen><verb>
1354 Odr_oid *odr_oiddup(ODR odr, Odr_oid *o);
1355 </verb></tscreen>
1356
1357 Creates a copy of the OID referenced by the <it/o/ parameter. Both
1358 functions take an <bf/ODR/ stream as parameter. This stream is used to
1359 allocate memory for the data elements, which is released on a
1360 subsequent call to <tt/odr_reset()/ on that stream.
1361
1362 The <bf/OID/ module provides a higher-level representation of the
1363 family of object identifers which describe the Z39.50 protocol and its
1364 related objects. The definition of the module interface is given in
1365 the <tt/oid.h/ file.
1366
1367 The interface is mainly based on the <tt/oident/ structure. The
1368 definition of this structure looks like this:
1369
1370 <tscreen><verb>
1371 typedef struct oident
1372 {
1373     oid_proto proto;
1374     oid_class oclass;
1375     oid_value value;
1376     int oidsuffix[OID_SIZE];
1377     char *desc;
1378 } oident;
1379 </verb></tscreen>
1380
1381 The <it/proto/ field takes one of the values
1382
1383 <tscreen><verb>
1384 PROTO_Z3950
1385 PROTO_SR
1386 </verb></tscreen>
1387
1388 If you don't care about talking to SR-based implementations (few
1389 exist, and they may become fewer still if and when the ISO SR and ANSI
1390 Z39.50 documents are merged into a single standard), you can ignore
1391 this field on incoming packages, and always set it to PROTO_Z3950
1392 for outgoing packages.
1393
1394 The <it/oclass/ field takes one of the values
1395
1396 <tscreen><verb>
1397 CLASS_APPCTX
1398 CLASS_ABSYN
1399 CLASS_ATTSET
1400 CLASS_TRANSYN
1401 CLASS_DIAGSET
1402 CLASS_RECSYN
1403 CLASS_RESFORM
1404 CLASS_ACCFORM
1405 CLASS_EXTSERV
1406 CLASS_USERINFO
1407 CLASS_ELEMSPEC
1408 CLASS_VARSET
1409 CLASS_SCHEMA
1410 CLASS_TAGSET
1411 CLASS_GENERAL
1412 </verb></tscreen>
1413
1414 corresponding to the OID classes defined by the Z39.50 standard.
1415
1416 Finally, the <it/value/ field takes one of the values
1417
1418 <tscreen><verb>
1419 VAL_APDU
1420 VAL_BER
1421 VAL_BASIC_CTX
1422 VAL_BIB1
1423 VAL_EXP1
1424 VAL_EXT1
1425 VAL_CCL1
1426 VAL_GILS
1427 VAL_WAIS
1428 VAL_STAS
1429 VAL_DIAG1
1430 VAL_ISO2709
1431 VAL_UNIMARC
1432 VAL_INTERMARC
1433 VAL_CCF
1434 VAL_USMARC
1435 VAL_UKMARC
1436 VAL_NORMARC
1437 VAL_LIBRISMARC
1438 VAL_DANMARC
1439 VAL_FINMARC
1440 VAL_MAB
1441 VAL_CANMARC
1442 VAL_SBN
1443 VAL_PICAMARC
1444 VAL_AUSMARC
1445 VAL_IBERMARC
1446 VAL_EXPLAIN
1447 VAL_SUTRS
1448 VAL_OPAC
1449 VAL_SUMMARY
1450 VAL_GRS0
1451 VAL_GRS1
1452 VAL_EXTENDED
1453 VAL_RESOURCE1
1454 VAL_RESOURCE2
1455 VAL_PROMPT1
1456 VAL_DES1
1457 VAL_KRB1
1458 VAL_PRESSET
1459 VAL_PQUERY
1460 VAL_PCQUERY
1461 VAL_ITEMORDER
1462 VAL_DBUPDATE
1463 VAL_EXPORTSPEC
1464 VAL_EXPORTINV
1465 VAL_NONE
1466 VAL_SETM
1467 VAL_SETG
1468 VAL_VAR1
1469 VAL_ESPEC1
1470 </verb></tscreen>
1471
1472 again, corresponding to the specific OIDs defined by the standard.
1473
1474 The <it/desc/ field contains a brief, mnemonic name for the OID in
1475 question.
1476
1477 The function
1478
1479 <tscreen><verb>
1480 struct oident *oid_getentbyoid(int *o);
1481 </verb></tscreen>
1482
1483 takes as argument an OID, and returns a pointer to a static area
1484 containing an <tt/oident/ structure. You typically use this function
1485 when you receive a PDU containing an OID, and you wish to branch out
1486 depending on the specific OID value.
1487
1488 The function
1489
1490 <tscreen><verb>
1491 int *oid_ent_to_oid(struct oident *ent, int *dst);
1492 </verb></tscreen>
1493
1494 Takes as argument an <tt/oident/ structure - in which the <it/proto/,
1495 <it/oclass/, and <it/value/ fields are assumed to be set correctly -
1496 and returns a pointer to a the buffer as given by <it/dst/
1497 containing the base
1498 representation of the corresponding OID. The function returns
1499 NULL and the array dst is unchanged if a mapping couldn't place.
1500 The array <it/dst/ should be at least of size <tt>OID_SIZE</tt>.
1501
1502 The <tt/oid_ent_to_oid()/ function can be used whenever you need to
1503 prepare a PDU containing one or more OIDs. The separation of the
1504 <it/protocol/ element from the remainer of the OID-description makes
1505 it simple to write applications that can communicate with either
1506 Z39.50 or OSI SR-based applications.
1507
1508 The function
1509
1510 <tscreen><verb>
1511 oid_value oid_getvalbyname(const char *name);
1512 </verb></tscreen>
1513
1514 takes as argument a mnemonic OID name, and returns the <it/value/
1515 field of the first entry in the database that contains the given name
1516 in its <it/desc/ field.
1517
1518 Finally, the module provides the following utility functions, whose
1519 meaning should be obvious:
1520
1521 <tscreen><verb>
1522 void oid_oidcpy(int *t, int *s);
1523 void oid_oidcat(int *t, int *s);
1524 int oid_oidcmp(int *o1, int *o2);
1525 int oid_oidlen(int *o);
1526 </verb></tscreen>
1527
1528 <it>
1529 NOTE: The <bf/OID/ module has been criticized - and perhaps rightly so
1530 - for needlessly abstracting the
1531 representation of OIDs. Other toolkits use a simple
1532 string-representation of OIDs with good results. In practice, we have
1533 found the interface comfortable and quick to work with, and it is a
1534 simple matter (for what it's worth) to create applications compatible
1535 with both ISO SR and Z39.50. Finally, the use of the <tt/oident/
1536 database is by no means mandatory. You can easily create your
1537 own system for representing OIDs, as long as it is compatible with the
1538 low-level integer-array representation of the ODR module.
1539 </it>
1540
1541 <sect1>Nibble Memory
1542
1543 <p>
1544 Sometimes when you need to allocate and construct a large,
1545 interconnected complex of structures, it can be a bit of a pain to
1546 release the associated memory again. For the structures describing the
1547 Z39.50 PDUs and related structures, it is convenient to use the
1548 memory-management system of the <bf/ODR/ subsystem (see
1549 <ref id="odr-use" name="Using ODR">). However, in some circumstances
1550 where you might otherwise benefit from using a simple nibble memory
1551 management system, it may be impractical to use <tt/odr_malloc()/ and
1552 <bf/odr_reset()/. For this purpose, the memory manager which also
1553 supports the <bf/ODR/ streams is made available in the <bf/NMEM/
1554 module. The external interface to this module is given in the
1555 <tt/nmem.h/ file.
1556
1557 The following prototypes are given:
1558
1559 <tscreen><verb>
1560 NMEM nmem_create(void);
1561 void nmem_destroy(NMEM n);
1562 void *nmem_malloc(NMEM n, int size);
1563 void nmem_reset(NMEM n);
1564 int nmem_total(NMEM n);
1565 void nmem_init(void);
1566 </verb></tscreen>
1567
1568 The <tt/nmem_create()/ function returns a pointer to a memory control
1569 handle, which can be released again by <tt/nmem_destroy()/ when no
1570 longer needed. The function <tt/nmem_malloc()/ allocates a block of
1571 memory of the requested size. A call to <tt/nmem_reset()/ or
1572 <tt/nmem_destroy()/ will release all memory allocated on the handle
1573 since it was created (or since the last call to
1574 <tt/nmem_reset()/. The function <tt/nmem_total()/ returns the number
1575 of bytes currently allocated on the handle.
1576
1577 Note that the nibble memory pool is shared amonst threads. Posix
1578 mutex'es and WIN32 Critical sections are introduced to keep the
1579 module thread safe. On WIN32 function <tt/nmem_init()/ initialises
1580 the Critical Section handle and should be called once before any
1581 other nmem function is used.
1582
1583 <sect>The ODR Module<label id="odr">
1584
1585 <sect1>Introduction
1586
1587 <p>
1588 <bf/ODR/ is the BER-encoding/decoding subsystem of <bf/YAZ/. Care as been taken
1589 to isolate <bf/ODR/ from the rest of the package - specifically from the
1590 transport interface. <bf/ODR/ may be used in any context where basic
1591 ASN.1/BER representations are used.
1592
1593 If you are only interested in writing a Z39.50 implementation based on
1594 the PDUs that are already provided with <bf/YAZ/, you only need to concern
1595 yourself with the section on managing ODR streams (section
1596 <ref id="odr-use" name="Using ODR">). Only if you need to
1597 implement ASN.1 beyond that which has been provided, should you
1598 worry about the second half of the documentation
1599 (section <ref id="odr-prog" name="Programming with ODR">). If you use
1600 one of the higher-level interfaces, you can skip this section entirely.
1601
1602 This is important, so we'll repeat it for emphasis: <it>You do not
1603 need to read section <ref id="odr-prog" name="Programming with ODR"> to
1604 implement Z39.50 with <bf/YAZ/.</it>
1605
1606 If you need a part of the protocol that isn't already in <bf/YAZ/, you
1607 should
1608 contact the authors before going to work on it yourself: We
1609 might already be working on it. Conversely, if you implement a useful
1610 part of the protocol before us, we'd be happy to include it in a
1611 future release.
1612
1613 <sect1>Using ODR<label id="odr-use">
1614
1615 <p>
1616 <sect2>ODR Streams
1617
1618 <p>
1619 Conceptually, the ODR stream is the source of encoded data in the
1620 decoding mode; when encoding, it is the receptacle for the encoded
1621 data. Before you can use an ODR stream it must be allocated. This is
1622 done with the function
1623
1624 <tscreen><verb>
1625 ODR odr_createmem(int direction);
1626 </verb></tscreen>
1627
1628 The <tt/odr_createmem()/ function takes as argument one of three manifest
1629 constants: <tt/ODR_ENCODE/, <tt/ODR_DECODE/, or <tt/ODR_PRINT/. An
1630 ODR stream can be
1631 in only one mode - it is not possible to change its mode once it's
1632 selected. Typically, your program will allocate at least two ODR
1633 streams - one for decoding, and one for encoding.
1634
1635 When you're done with the stream, you can use
1636
1637 <tscreen><verb>
1638 void odr_destroy(ODR o);
1639 </verb></tscreen>
1640
1641 to release the resources allocated for the stream.
1642
1643 <sect2>Memory Management<label id="memory">
1644
1645 <p>
1646 Two forms of memory management take place in the ODR system. The first
1647 one, which has to do with allocating little bits of memory (sometimes
1648 quite large bits of memory, actually) when a protocol package is
1649 decoded, and turned into a complex of interlinked structures. This
1650 section deals with this system, and how you can use it for your own
1651 purposes. The next section deals with the memory management which is
1652 required when encoding data - to make sure that a large enough buffer is
1653 available to hold the fully encoded PDU.
1654
1655 The <bf/ODR/ module has its own memory management system, which is
1656 used whenever memory is required. Specifically, it is used to allocate
1657 space for data when decoding incoming PDUs. You can use the memory
1658 system for your own purposes, by using the function
1659
1660 <tscreen><verb>
1661 void *odr_malloc(ODR o, int size);
1662 </verb></tscreen>
1663
1664 You can't use the normal <tt/free/(2) routine to free memory allocated
1665 by this function, and <bf/ODR/ doesn't provide a parallel function. Instead,
1666 you can call
1667
1668 <tscreen><verb>
1669 void odr_reset(ODR o, int size);
1670 </verb></tscreen>
1671
1672 when you are done with the
1673 memory: Everything allocated since the last call to <tt/odr_reset()/ is
1674 released. The <tt/odr_reset()/ call is also required to clear up an
1675 error condition on a stream.
1676
1677 The function
1678
1679 <tscreen><verb>
1680 int odr_total(ODR o);
1681 </verb></tscreen>
1682
1683 returns the number of bytes allocated on the stream since the last call to
1684 <tt/odr_reset()/.
1685
1686 The memory subsystem of <bf/ODR/ is fairly efficient at allocating and
1687 releasing little bits of memory. Rather than managing the individual,
1688 small bits of space, the system maintains a freelist of larger chunks
1689 of memory, which are handed out in small bits. This scheme is
1690 generally known as a <it/nibble memory/ system. It is very useful for
1691 maintaing short-lived constructions such as protocol PDUs.
1692
1693 If you want to retain a bit of memory beyond the next call to
1694 <tt/odr_reset()/, you can use the function
1695
1696 <tscreen><verb>
1697 ODR_MEM odr_extract_mem(ODR o);
1698 </verb></tscreen>
1699
1700 This function will give you control of the memory recently allocated
1701 on the ODR stream. The memory will live (past calls to <tt/odr_reset()/),
1702 until you call the function
1703
1704 <tscreen><verb>
1705 void odr_release_mem(ODR_MEM p);
1706 </verb></tscreen>
1707
1708 The opaque <tt/ODR_MEM/ handle has no other purpose than referencing
1709 the memory block for you until you want to release it.
1710
1711 You can use <tt/odr_extract_mem()/ repeatedly between allocating data,
1712 to retain individual control of separate chunks of data.
1713
1714 <sect2>Encoding and Decoding Data
1715
1716 <p>
1717 When encoding data, the ODR stream will write the encoded octet string
1718 in an internal buffer. To retrieve the data, use the function
1719
1720 <tscreen><verb>
1721 char *odr_getbuf(ODR o, int *len, int *size);
1722 </verb></tscreen>
1723
1724 The integer pointed to by len is set to the length of the encoded
1725 data, and a pointer to that data is returned. *<tt/size/ is set to the size
1726 of the buffer (unless <tt/size/ is null, signalling that you are
1727 not interested in the size). The next call to a primitive function
1728 using the same ODR stream will overwrite the data, unless a different
1729 buffer has been supplied using the call
1730
1731 <tscreen><verb>
1732 void odr_setbuf(ODR o, char *buf, int len, int can_grow);
1733 </verb></tscreen>
1734
1735 which sets the encoding (or decoding) buffer used by <tt/o/ to
1736 <tt/buf/,
1737 using the length <tt/len/. Before a call to an encoding function,
1738 you can use <tt/odr_setbuf()/ to provide the stream with an encoding buffer
1739 of sufficient size (length). The <tt/can_grow/ parameter tells the encoding
1740 ODR stream whether it is allowed to use <tt/realloc/(2) to increase the size
1741 of the buffer when necessary. The default condition of a new encoding
1742 stream is equivalent to the results of calling
1743
1744 <tscreen><verb>
1745 odr_setbuf(stream, 0, 0, 1);
1746 </verb></tscreen>
1747
1748 In this case, the stream will allocate and reallocate memory as
1749 necessary. The stream reallocates memory by repeatedly doubling the
1750 size of the buffer - the result is that the buffer will typically
1751 reach its maximum, working size with only a small number of reallocation
1752 operations. The memory is freed by the stream when the latter is destroyed,
1753 unless it was assigned by the user with the <tt/can_grow/
1754 parameter set to zero (in this case, you are expected to retain
1755 control of the memory yourself).
1756
1757 To assume full control of an encoded buffer, you must first call
1758 <tt/odr_getbuf()/ to fetch the buffer and its length. Next, you should
1759 call <tt/odr_setbuf()/ to provide a different buffer (or a null
1760 pointer) to the stream. In the simplest case, you will reuse the same
1761 buffer over and over again, and you will just need to call
1762 <tt/odr_getbuf()/ after each encoding operation to get the length and
1763 address of the buffer. Note that the stream may reallocate the buffer
1764 during an encoding operation, so it is necessary to retrieve the
1765 correct address after each encoding operation.
1766
1767 It is important to realise that the ODR stream will not release this
1768 memory when you call <tt/odr_reset()/: It will merely update its
1769 internal pointers to prepare for the encoding of a new data value.
1770 When the stream is released by the <tt/odr_destroy()/ function, the
1771 memory given to it by odr_setbuf will be released <it/only/ if the
1772 <tt/can_grow/ parameter to <tt/odr_setbuf()/ was nonzero. The
1773 <tt/can_grow/ parameter, in other words, is a way of signalling who
1774 is to own the buffer, you or the ODR stream. If you never call
1775 <tt/odr_setbuf()/ on your encoding stream, which is typically the
1776 case, the buffer allocated by the stream will belong to the stream by
1777 default.
1778
1779 When you wish to decode data, you should first call <tt/odr_setbuf()/, to
1780 tell the decoding stream where to find the encoded data, and how long
1781 the buffer is (the <tt/can_grow/ parameter is ignored by a decoding
1782 stream). After this, you can call the function corresponding to the
1783 data you wish to decode (eg, <tt/odr_integer()/ odr <tt/z_APDU()/).
1784
1785 Examples of encoding/decoding functions:
1786
1787 <tscreen><verb>
1788 int odr_integer(ODR o, int **p, int optional, const char *name);
1789
1790 int z_APDU(ODR o, Z_APDU **p, int optional, const char *name);
1791 </verb></tscreen>
1792
1793 If the data is absent (or
1794 doesn't match the tag corresponding to the type), the return value
1795 will be either 0 or 1 depending on the <tt/optional/ flag. If
1796 <tt/optional/
1797 is 0 and the data is absent, an error flag will be raised in the
1798 stream, and you'll need to call <tt/odr_reset()/ before you can use the
1799 stream again. If <tt/optional/ is nonzero, the pointer <it/pointed to/ by
1800 <tt/p/ will be set to the null value, and the function will return 1.
1801 The <tt/name/ argument is used to pretty-print the tag in question.
1802 It may be set to <tt/NULL/ if pretty-printing is not desired.
1803
1804 If the data value is found where it's expected, the pointer
1805 <it/pointed to/ by the <tt/p/ argument will be set to point to the
1806 decoded type. The
1807 space for the type will be allocated and owned by the ODR stream, and
1808 it will live until you call <tt/odr_reset()/ on the stream. You cannot use
1809 <tt/free/(2) to release the memory. You can decode several data elements
1810 (by repeated calls to <tt/odr_setbuf()/ and your decoding function), and
1811 new memory will be allocated each time. When you do call
1812 <tt/odr_reset()/,
1813 everything decoded since the last call to <tt/odr_reset()/ will be
1814 released.
1815
1816 The use of the double indirection can be a little confusing at first
1817 (its purpose will become clear later on, hopefully),
1818 so an example is in order. We'll encode an integer value, and
1819 immediately decode it again using a different stream. A useless, but
1820 informative operation.
1821
1822 <tscreen><verb>
1823 void do_nothing_useful(int value)
1824 {
1825     ODR encode, decode;
1826     int *valp, *resvalp;
1827     char *bufferp;
1828     int len;
1829
1830     /* allocate streams */
1831     if (!(encode = odr_createmem(ODR_ENCODE)))
1832         return;
1833     if (!(decode = odr_createmem(ODR_DECODE)))
1834         return;
1835
1836     valp = &ero;value;
1837     if (odr_integer(encode, &ero;valp, 0, 0) == 0)
1838     {
1839         printf("encoding went bad\n");
1840         return;
1841     }
1842     bufferp = odr_getbuf(encode, &ero;len);
1843     printf("length of encoded data is &percnt;d\n", len);
1844
1845     /* now let's decode the thing again */
1846     odr_setbuf(decode, bufferp, len);
1847     if (odr_integer(decode, &ero;resvalp, 0, 0) == 0)
1848     {
1849         printf("decoding went bad\n");
1850         return;
1851     }
1852     printf("the value is &percnt;d\n", *resvalp);
1853
1854     /* clean up */
1855     odr_destroy(encode);
1856     odr_destroy(decode);
1857 }
1858 </verb></tscreen>
1859
1860 This looks like a lot of work, offhand. In practice, the ODR streams
1861 will typically be allocated once, in the beginning of your program (or at the
1862 beginning of a new network session), and the encoding and decoding
1863 will only take place in a few, isolated places in your program, so the
1864 overhead is quite manageable.
1865
1866 <sect2>Diagnostics
1867
1868 <p>
1869 The encoding/decoding functions all return 0 when an error occurs.
1870 Until you call <tt/odr_reset()/, you cannot use the stream again, and
1871 any function called will immediately return 0.
1872
1873 To provide information to the programmer or administrator, the
1874 function
1875
1876 <tscreen><verb>
1877 void odr_perror(ODR o, char *message);
1878 </verb></tscreen>
1879
1880 is provided, which prints the <tt/message/ argument to <tt/stderr/
1881 along with an error message from the stream.
1882
1883 You can also use the function
1884
1885 <tscreen><verb>
1886 int odr_geterror(ODR o);
1887 </verb></tscreen>
1888
1889 to get the current error number from the screen. The number will be
1890 one of these constants:
1891
1892 <descrip>
1893 <tag/OMEMORY/Memory allocation failed.
1894 <tag/OSYSERR/A system- or library call has failed. The standard
1895 diagnostic variable <tt/errno/
1896 should be examined to determine the actual error.
1897 <tag/OSPACE/No more space for encoding. This will only occur when the user has
1898 explicitly provided a buffer for an encoding stream without allowing
1899 the system to allocate more space.
1900 <tag/OREQUIRED/This is a common protocol error; A required data element was
1901 missing during
1902 encoding or decoding.
1903 <tag/OUNEXPECTED/An unexpected data element was found during decoding.
1904 <tag/OOTHER/Other error. This is typically an indication of misuse of
1905 the <bf/ODR/ system by the programmer, and also that the diagnostic
1906 system isn't as good as it should be, yet.
1907 </descrip>
1908
1909 The character string array
1910
1911 <tscreen><verb>
1912 char *odr_errlist&lsqb;&rsqb;
1913 </verb></tscreen>
1914
1915 can be indexed by the error code to obtain a human-readable
1916 representation of the problem.
1917
1918 <sect2>Summary and Synopsis
1919
1920 <p>
1921 <tscreen><verb>
1922 #include <odr.h>
1923
1924 ODR odr_createmem(int direction);
1925
1926 void odr_destroy(ODR o);
1927
1928 void odr_reset(ODR o);
1929
1930 char *odr_getbuf(ODR o, int *len);
1931
1932 void odr_setbuf(ODR o, char *buf, int len);
1933
1934 void *odr_malloc(ODR o, int size);
1935
1936 ODR_MEM odr_extract_mem(ODR o);
1937
1938 void odr_release_mem(ODR_MEM r);
1939
1940 int odr_geterror(ODR o);
1941
1942 void odr_perror(char *message);
1943
1944 extern char *odr_errlist[];
1945 </verb></tscreen>
1946
1947 <sect1>Programming with ODR<label id="odr-prog">
1948
1949 <p>
1950 The API of <bf/ODR/ is designed to reflect the structure of ASN.1, rather
1951 than BER itself. Future releases may be able to represent data in
1952 other external forms.
1953
1954 The interface is based loosely on that of the Sun Microsystems XDR routines.
1955 Specifically, each function which corresponds to an ASN.1 primitive
1956 type has a dual function. Depending on the settings of the ODR
1957 stream which is supplied as a parameter, the function may be used
1958 either to encode or decode data. The functions that can be built
1959 using these primitive functions, to represent more complex datatypes, share
1960 this quality. The result is that you only have to enter the definition
1961 for a type once - and you have the functionality of encoding, decoding
1962 (and pretty-printing) all in one unit. The resulting C source code is
1963 quite compact, and is a pretty straightforward representation of the
1964 source ASN.1 specification. Although no ASN.1 compiler is supplied
1965 with <bf/ODR/ at this time, it shouldn't be too difficult to write one, or
1966 perhaps even to adapt an existing compiler to output <bf/ODR/ routines
1967 (not surprisingly, writing encoders/decoders using <bf/ODR/ turns out
1968 to be boring work).
1969
1970 In many cases, the model of the XDR functions works quite well in this
1971 role. In
1972 others, it is less elegant. Most of the hassle comes from the optional
1973 SEQUENCE memebers which don't exist in XDR.
1974
1975 <sect2>The Primitive ASN.1 Types
1976
1977 <p>
1978 ASN.1 defines a number of primitive types (many of which correspond
1979 roughly to
1980 primitive types in structured programming languages, such as C).
1981
1982 <sect3>INTEGER
1983
1984 <p>
1985 The <bf/ODR/ function for encoding or decoding (or printing) the ASN.1
1986 INTEGER type looks like this:
1987
1988 <tscreen><verb>
1989 int odr_integer(ODR o, int **p, int optional, const char *name);
1990 </verb></tscreen>
1991
1992 (we don't allow values that can't be contained in a C integer.)
1993
1994 This form is typical of the primitive <bf/ODR/ functions. They are named
1995 after the type of data that they encode or decode. They take an
1996 ODR
1997 stream, an indirect reference to the type in question, and an
1998 <tt/optional/ flag (corresponding to the OPTIONAL keyword of ASN.1) as
1999 parameters. They all return an integer value of either one or zero.
2000 When you use the primitive functions to construct encoders for complex
2001 types of your own, you should follow this model as well. This
2002 ensures that your new types can be reused as elements in yet more
2003 complex types.
2004
2005 The <tt/o/ parameter should obviously refer to a properly
2006 initialized ODR
2007 stream of the right type (encoding/decoding/printing) for the
2008 operation that you wish to perform.
2009
2010 When encoding or printing, the function first looks at *<tt/p/. If
2011 *<tt/p/ (the
2012 pointer pointed to by <tt/p/) is a null pointer, this is taken to mean that
2013 the data element is absent. If the <tt/optional/ parameter is nonzero,
2014 the function will return one (signifying success) without any further
2015 processing. If the <tt/optional/ is zero, an internal error flag is
2016 set in the ODR stream, and the function will return 0. No further
2017 operations can be carried out on the stream without a call to
2018 the function <tt/odr_reset()/.
2019
2020 If *<tt/p/ is not a null pointer, it is expected to point to an instance of
2021 the data type. The data will be subjected to the encoding rules, and
2022 the result will be placed in the buffer held by the ODR stream.
2023
2024 The other ASN.1 primitives have similar functions that operate in
2025 similar manners:
2026
2027 <sect3>BOOLEAN
2028
2029 <p>
2030 <tscreen><verb>
2031 int odr_bool(ODR o, bool_t **p, int optional, const char *name);
2032 </verb></tscreen>
2033
2034 <sect3>REAL
2035
2036 <p>
2037 Not defined.
2038
2039 <sect3>NULL
2040
2041 <p>
2042 <tscreen><verb>
2043 int odr_null(ODR o, bool_t **p, int optional, const char *name);
2044 </verb></tscreen>
2045
2046 In this case, the value of **p is not important. If *p is different
2047 from the null pointer, the null value is present, otherwise it's
2048 absent.
2049
2050 <sect3>OCTET STRING
2051
2052 <p>
2053 <tscreen><verb>
2054 typedef struct odr_oct
2055 {
2056     unsigned char *buf;
2057     int len;
2058     int size;
2059 } Odr_oct;
2060
2061 int odr_octetstring(ODR o, Odr_oct **p, int optional, const char *name);
2062 </verb></tscreen>
2063
2064 The <tt/buf/ field should point to the character array that holds the
2065 octetstring. The <tt/len/ field holds the actual length, while the
2066 <tt/size/
2067 field gives the size of the allocated array (not of interest to you,
2068 in most cases). The character array need not be null terminated.
2069
2070 To make things a little easier, an alternative is given for string
2071 types that are not expected to contain embedded NULL characters (eg.
2072 VisibleString):
2073
2074 <tscreen><verb>
2075 int odr_cstring(ODR o, char **p, int optional, const char *name);
2076 </verb></tscreen>
2077
2078 Which encoded or decodes between OCTETSTRING representations and
2079 null-terminates C strings.
2080
2081 Functions are provided for the derived string types, eg:
2082
2083 <tscreen><verb>
2084 int odr_visiblestring(ODR o, char **p, int optional, const char *name);
2085 </verb></tscreen>
2086
2087 <sect3>BIT STRING
2088
2089 <p>
2090 <tscreen><verb>
2091 int odr_bitstring(ODR o, Odr_bitmask **p, int optional, const char *name);
2092 </verb></tscreen>
2093
2094 The opaque type <tt/Odr_bitmask/ is only suitable for holding relatively brief bit
2095 strings, eg. for options fields, etc. The constant
2096 <tt/ODR_BITMASK_SIZE/
2097 multiplied by 8 gives the maximum possible number of bits.
2098
2099 A set of macros are provided for manipulating the
2100 <tt/Odr_bitmask/
2101 type:
2102
2103 <tscreen><verb>
2104 void ODR_MASK_ZERO(Odr_bitmask *b);
2105
2106 void ODR_MASK_SET(Odr_bitmask *b, int bitno);
2107
2108 void ODR_MASK_CLEAR(Odr_bitmask *b, int bitno);
2109
2110 int ODR_MASK_GET(Odr_bitmask *b, int bitno);
2111 </verb></tscreen>
2112
2113 The functions are modelled after the manipulation functions that
2114 accompany the <tt/fd_set/ type used by the <tt/select/(2) call.
2115 <tt/ODR_MASK_ZERO/ should always be called first on a new bitmask, to
2116 initialize the bits to zero.
2117
2118 <sect3>OBJECT IDENTIFIER
2119
2120 <p>
2121 <tscreen><verb>
2122 int odr_oid(ODR o, Odr_oid **p, int optional, const char *name);
2123 </verb></tscreen>
2124
2125 The C OID represenation is simply an array of integers, terminated by
2126 the value -1 (the <tt/Odr_oid/ type is synonymous with the <tt/int/
2127 type). We suggest that you use the OID database module (see section
2128 <ref id="oid" name="Object Identifiers">) to handle object identifiers
2129 in your application.
2130
2131 <sect2>Tagging Primitive Types<label id="tag-prim">
2132
2133 <p>
2134 The simplest way of tagging a type is to use the <tt/odr_implicit_tag()/ or
2135 <tt/odr_explicit_tag()/ macros:
2136
2137 <tscreen><verb>
2138 int odr_implicit_tag(ODR o, Odr_fun fun, int class, int tag, int
2139                      optional, const char *name);
2140
2141 int odr_explicit_tag(ODR o, Odr_fun fun, int class, int tag,
2142                      int optional, const char *name);
2143 </verb></tscreen>
2144
2145 To create a type derived from the integer type by implicit tagging, you
2146 might write:
2147
2148 <tscreen><verb>
2149 MyInt ::= &lsqb;210&rsqb; IMPLICIT INTEGER
2150 </verb></tscreen>
2151
2152 In the <bf/ODR/ system, this would be written like:
2153
2154 <tscreen><verb>
2155 int myInt(ODR o, int **p, int optional, const char *name)
2156 {
2157     return odr_implicit_tag(o, odr_integer, p,
2158                    ODR_CONTEXT, 210, optional, name);
2159 }
2160 </verb></tscreen>
2161
2162 The function <tt/myInt()/ can then be used like any of the primitive
2163 functions provided by ODR. Note that the behavior of
2164 <tt/odr_explicit()/
2165 and <tt/odr_implicit()/ macros act exactly the same as the functions they
2166 are applied to - they respond to error conditions, etc, in the same
2167 manner - they simply have three extra parameters. The class parameter may
2168 take one of the values: <tt/ODR_CONTEXT/, <tt/ODR_PRIVATE/,
2169 <tt/ODR_UNIVERSAL/, or
2170 <tt/ODR_APPLICATION/.
2171
2172 <sect2>Constructed Types
2173
2174 <p>
2175 Constructed types are created by combining primitive types. The
2176 <bf/ODR/
2177 system only implements the SEQUENCE and SEQUENCE OF constructions
2178 (although adding the rest of the container types should be simple
2179 enough, if the need arises).
2180
2181 For implementing SEQUENCEs, the functions
2182
2183 <tscreen><verb>
2184 int odr_sequence_begin(ODR o, void *p, int size, const char *name);
2185 int odr_sequence_end(ODR o);
2186 </verb></tscreen>
2187
2188 are provided.
2189
2190 The <tt/odr_sequence_begin()/ function should be called in the beginning of a
2191 function that implements a SEQUENCE type. Its parameters are the
2192 <bf/ODR/
2193 stream, a pointer (to a pointer to the type you're implementing), and
2194 the <tt/size/ of the type (typically a C structure). On encoding, it
2195 returns 1 if *<tt/p/ is a null pointer. The <tt/size/ parameter is ignored. On
2196 decoding, it returns 1 if the type is found in the data stream.
2197 <tt/size/
2198 bytes of memory are allocated, and *<tt/p/ is set to point to this space.
2199 <tt/odr_sequence_end()/ is called at the end of the complex function. Assume
2200 that a type is defined like this:
2201
2202 <tscreen><verb>
2203 MySequence ::= SEQUENCE {
2204     intval INTEGER,
2205     boolval BOOLEAN OPTIONAL }
2206 </verb></tscreen>
2207
2208 The corresponding ODR encoder/decoder function and the associated data
2209 structures could be written like this:
2210
2211 <tscreen><verb>
2212 typedef struct MySequence
2213 {
2214     int *intval;
2215     bool_t *boolval;
2216 } MySequence;
2217
2218 int mySequence(ODR o, MySequence **p, int optional, const char *name)
2219 {
2220     if (odr_sequence_begin(o, p, sizeof(**p), name) == 0)
2221         return optional &ero;&ero; odr_ok(o);
2222     return
2223         odr_integer(o, &ero;(*p)->intval, 0, "intval") &ero;&ero;
2224         odr_bool(o, &ero;(*p)->boolval, 1, "boolval") &ero;&ero;
2225         odr_sequence_end(o);
2226 }
2227 </verb></tscreen>
2228
2229 Note the 1 in the call to <tt/odr_bool()/, to mark that the sequence
2230 member is optional. If either of the member types had been tagged, the
2231 macros <tt/odr_implicit()/ or <tt/odr_explicit()/ could have been used.
2232 The new
2233 function can be used exactly like the standard functions provided with
2234 <bf/ODR/. It will encode, decode or pretty-print a data value of the
2235 <tt/MySequence/ type. We like to name types with an initial capital, as
2236 done in ASN.1 definitions, and to name the corresponding function with
2237 the first character of the name in lower case. You could, of course,
2238 name your structures, types, and functions any way you please - as
2239 long as you're consistent, and your code is easily readable.
2240 <tt/odr_ok/ is
2241 just that - a predicate that returns the state of the stream. It is
2242 used to ensure that the behaviour of the new type is compatible with
2243 the interface of the primitive types.
2244
2245 <sect2>Tagging Constructed Types
2246
2247 <p>
2248 <it>
2249 NOTE: See section <ref id="tag-prim" name="Tagging Primitive types">
2250 for information on how to tag the primitive types, as well as types
2251 that are already defined.
2252 </it>
2253
2254 <sect3>Implicit Tagging
2255
2256 <p>
2257 Assume the type above had been defined as
2258
2259 <tscreen><verb>
2260 MySequence ::= &lsqb;10&rsqb; IMPLICIT SEQUENCE {
2261     intval INTEGER,
2262     boolval BOOLEAN OPTIONAL }
2263 </verb></tscreen>
2264
2265 You would implement this in <bf/ODR/ by calling the function
2266
2267 <tscreen><verb>
2268 int odr_implicit_settag(ODR o, int class, int tag);
2269 </verb></tscreen>
2270
2271 which overrides the tag of the type immediately following it. The
2272 macro <tt/odr_implicit()/ works by calling <tt/odr_implicit_settag()/
2273 immediately
2274 before calling the function pointer argument. Your type function could
2275 look like this:
2276
2277 <tscreen><verb>
2278 int mySequence(ODR o, MySequence **p, int optional, const char *name)
2279 {
2280     if (odr_implicit_settag(o, ODR_CONTEXT, 10) == 0 ||
2281         odr_sequence_begin(o, p, sizeof(**p), name) == 0)
2282         return optional &ero;&ero; odr_ok(o);
2283     return
2284         odr_integer(o, &ero;(*p)->intval, 0, "intval") &ero;&ero;
2285         odr_bool(o, &ero;(*p)->boolval, 1, "boolval") &ero;&ero;
2286         odr_sequence_end(o);
2287 }
2288 </verb></tscreen>
2289
2290 The definition of the structure <tt/MySequence/ would be the same.
2291
2292 <sect3>Explicit Tagging
2293
2294 <p>
2295 Explicit tagging of constructed types is a little more complicated,
2296 since you are in effect adding a level of construction to the data.
2297
2298 Assume the definition:
2299
2300 <tscreen><verb>
2301 MySequence ::= &lsqb;10&rsqb; IMPLICIT SEQUENCE {
2302     intval INTEGER,
2303     boolval BOOLEAN OPTIONAL }
2304 </verb></tscreen>
2305
2306 Since the new type has an extra level of construction, two new functions
2307 are needed to encapsulate the base type:
2308
2309 <tscreen><verb>
2310 int odr_constructed_begin(ODR o, void *p, int class, int tag,
2311        const char *name);
2312
2313 int odr_constructed_end(ODR o);
2314 </verb></tscreen>
2315
2316 Assume that the IMPLICIT in the type definition above were replaced
2317 with EXPLICIT (or that the IMPLICIT keyword were simply deleted, which
2318 would be equivalent). The structure definition would look the same,
2319 but the function would look like this:
2320
2321 <tscreen><verb>
2322 int mySequence(ODR o, MySequence **p, int optional, const char *name)
2323 {
2324     if (odr_constructed_begin(o, p, ODR_CONTEXT, 10, name) == 0)
2325         return optional &ero;&ero; odr_ok(o);
2326     if (o->direction == ODR_DECODE)
2327         *p = odr_malloc(o, sizeof(**p));
2328     if (odr_sequence_begin(o, p, sizeof(**p), 0) == 0)
2329     {
2330         *p = 0; /* this is almost certainly a protocol error */
2331         return 0;
2332     }
2333     return
2334         odr_integer(o, &ero;(*p)->intval, 0, "intval") &ero;&ero;
2335         odr_bool(o, &ero;(*p)->boolval, 1, "boolval") &ero;&ero;
2336         odr_sequence_end(o) &ero;&ero;
2337         odr_constructed_end(o);
2338 }
2339 </verb></tscreen>
2340
2341 Notice that the interface here gets kind of nasty. The reason is
2342 simple: Explicitly tagged, constructed types are fairly rare in
2343 the protocols that we care about, so the
2344 aesthetic annoyance (not to mention the dangers of a cluttered
2345 interface) is less than the time that would be required to develop a
2346 better interface. Nevertheless, it is far from satisfying, and it's a
2347 point that will be worked on in the future. One option for you would
2348 be to simply apply the <tt/odr_explicit()/ macro to the first function,
2349 and not
2350 have to worry about <tt/odr_constructed_*/ yourself. Incidentally, as you
2351 might have guessed, the <tt/odr_sequence_/ functions are themselves
2352 implemented using the <tt/odr_constructed_/ functions.
2353
2354 <sect2>SEQUENCE OF
2355
2356 <p>
2357 To handle sequences (arrays) of a apecific type, the function
2358
2359 <tscreen><verb>
2360 int odr_sequence_of(ODR o, int (*fun)(ODR o, void *p, int optional),
2361                         void *p, int *num, const char *name);
2362 </verb></tscreen>
2363
2364 The <tt/fun/ parameter is a pointer to the decoder/encoder
2365 function of the type. <tt/p/ is a pointer to an array of pointers to your
2366 type. <tt/num/ is the number of elements in the array.
2367
2368 Assume a type
2369
2370 <tscreen><verb>
2371 MyArray ::= SEQUENCE OF INTEGER
2372 </verb></tscreen>
2373
2374 The C representation might be
2375
2376 <tscreen><verb>
2377 typedef struct MyArray
2378 {
2379     int num_elements;
2380     int **elements;
2381 } MyArray;
2382 </verb></tscreen>
2383
2384 And the function might look like
2385
2386 <tscreen><verb>
2387 int myArray(ODR o, MyArray **p, int optional, const char *name)
2388 {
2389     if (o->direction == ODR_DECODE)
2390         *p = odr_malloc(o, sizeof(**p));
2391     if (odr_sequence_of(o, odr_integer, &ero;(*p)->elements,
2392         &ero;(*p)->num_elements, name))
2393         return 1;
2394     *p = 0;
2395     return optional &ero;&ero; odr_ok(o);
2396 }
2397 </verb></tscreen>
2398
2399 <sect2>CHOICE Types
2400
2401 <p>
2402 The choice type is used fairly often in some ASN.1 definitions, so
2403 some work has gone into streamlining its interface.
2404
2405 CHOICE types are handled by the function:
2406
2407 <tscreen><verb>
2408 int odr_choice(ODR o, Odr_arm arm&lsqb;&rsqb;, void *p, void *whichp,
2409                const char *name);
2410 </verb></tscreen>
2411
2412 The <tt/arm/ array is used to describe each of the possible types that the
2413 CHOICE type may assume. Internally in your application, the CHOICE
2414 type is represented as a discriminated union. That is, a C union
2415 accompanied by an integer (or enum) identifying the active 'arm' of
2416 the union. <tt/whichp/ is a pointer to the union discriminator. When
2417 encoding, it is examined to determine the current type. When decoding,
2418 it is set to reference the type that was found in the input stream.
2419
2420 The Odr_arm type is defined thus:
2421
2422 <tscreen><verb>
2423 typedef struct odr_arm
2424 {
2425     int tagmode;
2426     int class;
2427     int tag;
2428     int which;
2429     Odr_fun fun;
2430     char *name;
2431 } Odr_arm;
2432 </verb></tscreen>
2433
2434 The interpretation of the fields are:
2435
2436 <descrip>
2437 <tag/tagmode/Either <tt/ODR_IMPLICIT/, <tt/ODR_EXPLICIT/, or <tt/ODR_NONE/
2438 (-1) to mark
2439 no tagging.
2440 <tag/class, tag/The class and tag of the type (-1 if no tagging is
2441 used).
2442 <tag/which/The value of the discriminator that corresponds to
2443 this CHOICE element. Typically, it will be a &num;defined constant, or
2444 an enum member.
2445 <tag/fun/A pointer to a function that implements the type of
2446 the CHOICE member. It may be either a standard <bf/ODR/ type or a type
2447 defined by yourself.
2448 <tag/name/Name of tag.
2449 </descrip>
2450
2451 A handy way to prepare the array for use by the <tt/odr_choice()/ function
2452 is to
2453 define it as a static, initialized array in the beginning of your
2454 decoding/encoding function. Assume the type definition:
2455
2456 <tscreen><verb>
2457 MyChoice ::= CHOICE {
2458     untagged INTEGER,
2459     tagged   &lsqb;99&rsqb; IMPLICIT INTEGER,
2460     other    BOOLEAN
2461 }
2462 </verb></tscreen>
2463
2464 Your C type might look like
2465
2466 <tscreen><verb>
2467 typedef struct MyChoice
2468 {
2469     enum
2470     {
2471         MyChoice_untagged,
2472         MyChoice_tagged,
2473         MyChoice_other
2474     } which;
2475     union
2476     {
2477         int *untagged;
2478         int *tagged;
2479         bool_t *other;
2480     } u;
2481 };
2482 </verb></tscreen>
2483
2484 And your function could look like this:
2485
2486 <tscreen><verb>
2487 int myChoice(ODR o, MyChoice **p, int optional, const char *name)
2488 {
2489     static Odr_arm arm&lsqb;&rsqb; =
2490     {
2491         {-1, -1, -1, MyChoice_untagged, odr_integer, "untagged"},
2492         {ODR_IMPLICIT, ODR_CONTEXT, 99, MyChoice_tagged, odr_integer,
2493                                                             "tagged"},
2494         {-1, -1, -1, MyChoice_other, odr_boolean, "other"},
2495         {-1, -1, -1, -1, 0}
2496     };
2497
2498     if (o->direction == ODR_DECODE)
2499         *p = odr_malloc(o, sizeof(**p);
2500     else if (!*p)
2501         return optional &ero;&ero; odr_ok(o);
2502
2503     if (odr_choice(o, arm, &ero;(*p)->u, &ero;(*p)->which), name)
2504         return 1;
2505     *p = 0;
2506     return optional &ero;&ero; odr_ok(o);
2507 }
2508 </verb></tscreen>
2509
2510 In some cases (say, a non-optional choice which is a member of a sequence),
2511 you can &dquot;embed&dquot; the union and its discriminator in the structure
2512 belonging to the enclosing type, and you won't need to fiddle with
2513 memory allocation to create a separate structure to wrap the
2514 discriminator and union.
2515
2516 The corresponding function is somewhat nicer in the Sun XDR interface.
2517 Most of the complexity of this interface comes from the possibility of
2518 declaring sequence elements (including CHOICEs) optional.
2519
2520 The ASN.1 specifictions naturally requires that each member of a
2521 CHOICE have a distinct tag, so they can be told apart on decoding.
2522 Sometimes it can be useful to define a CHOICE that has multiple types
2523 that share the same tag. You'll need some other mechanism, perhaps
2524 keyed to the context of the CHOICE type. In effect, we would like to
2525 introduce a level of context-sensitiveness to our ASN.1 specification.
2526 When encoding an internal representation, we have no problem, as long
2527 as each CHOICE member has a distinct discriminator value. For
2528 decoding, we need a way to tell the choice function to look for a
2529 specific arm of the table. The function
2530
2531 <tscreen><verb>
2532 void odr_choice_bias(ODR o, int what);
2533 </verb></tscreen>
2534
2535 provides this functionality. When called, it leaves a notice for the
2536 next call to <tt/odr_choice()/ to be called on the decoding
2537 stream <tt/o/ that only the <tt/arm/ entry with a <tt/which/ field
2538 equal to <tt/what/ should be tried.
2539
2540 The most important application (perhaps the only one, really) is in
2541 the definition of application-specific EXTERNAL encoders/decoders
2542 which will automatically decode an ANY member given the direct or
2543 indirect reference.
2544
2545 <sect1>Debugging
2546
2547 <p>
2548 The protocol modules are suffering somewhat from a lack of diagnostic
2549 tools at the moment. Specifically ways to pretty-print PDUs that
2550 aren't recognized by the system. We'll include something to this end
2551 in a not-too-distant release. In the meantime, what we do when we get
2552 packages we don't understand is to compile the ODR module with
2553 <tt/ODR_DEBUG/ defined. This causes the module to dump tracing
2554 information as it processes data units. With this output and the
2555 protocol specification (Z39.50), it is generally fairly easy to see
2556 what goes wrong.
2557
2558 <sect>The COMSTACK Module<label id="comstack">
2559
2560 <sect1>Introduction
2561
2562 <p>
2563 The <bf/COMSTACK/
2564 subsystem provides a transparent interface to different types of transport
2565 stacks for the exchange of BER-encoded data. At present, the
2566 RFC1729 method (BER over TCP/IP), and Peter Furniss' XTImOSI
2567 stack are supported, but others may be added in time. The philosophy of the
2568 module is to provide a simple interface by hiding unused options and
2569 facilities of the underlying libraries. This is always done at the risk
2570 of losing generality, and it may prove that the interface will need
2571 extension later on.
2572
2573 The interface is implemented in such a fashion that only the
2574 sub-layers constructed to the transport methods that you wish to
2575 use in your application are linked in.
2576
2577 You will note that even though simplicity was a goal in the design,
2578 the interface is still orders of magnitudes more complex than the
2579 transport systems found in many other packages. One reason is that
2580 the interface needs to support the somewhat different requirements of
2581 the different lower-layer communications stacks; another important reason is
2582 that the interface seeks to provide a more or less industrial-strength
2583 approach to asynchronous event-handling. When no function is allowed
2584 to block, things get more complex - particularly on the server
2585 side. We urge you to have a look at the demonstration client and server
2586 provided with the package. They are meant to be easily readable and
2587 instructive, while still being at least moderately useful.
2588
2589 <sect1>Common Functions
2590
2591 <sect2>Managing Endpoints
2592
2593 <p>
2594 <tscreen><verb>
2595 COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
2596 </verb></tscreen>
2597
2598 Creates an instance of the protocol stack - a communications endpoint.
2599 The
2600 <tt/type/
2601 parameter determines the mode of communication. At present, the
2602 values
2603 <tt/tcpip_type/
2604 and
2605 <tt/mosi_type/
2606 are recognized. The function returns a null-pointer if a system error
2607 occurs. The <tt/blocking/ parameter should be one if you wish the
2608 association to operate in blocking mode, zero otherwise. The
2609 <tt/protocol/ field should be one of <tt/PROTO_SR/ or <tt/PROTO_Z3950/.
2610
2611 <tscreen><verb>
2612 int cs_close(COMSTACK handle);
2613 </verb></tscreen>
2614
2615 Closes the connection (as elegantly as the lower layers will permit),
2616 and releases the resouces pointed to by the
2617 <tt/handle/
2618 parameter. The
2619 <tt/handle/
2620 should not be referenced again after this call.
2621
2622 <it>
2623 NOTE:
2624 We really need a soft disconnect, don't we?
2625 </it>
2626
2627 <sect2>Data Exchange
2628
2629 <p>
2630 <tscreen><verb>
2631 int cs_put(COMSTACK handle, char *buf, int len);
2632 </verb></tscreen>
2633
2634 Sends
2635 <tt/buf/
2636 down the wire. In blocking mode, this function will return only when a
2637 full buffer has been written, or an error has occurred. In nonblocking
2638 mode, it's possible that the function will be unable to send the full
2639 buffer at once, which will be indicated by a return value of 1. The
2640 function will keep track of the number of octets already written; you
2641 should call it repeatedly with the same values of <tt/buf/ and
2642 <tt/len/, until the buffer has been transmitted. When a full buffer
2643 has been sent, the function will return 0 for success. -1 indicates
2644 an error condition (see below).
2645
2646 <tscreen><verb>
2647 int cs_get(COMSTACK handle, char **buf, int *size);
2648 </verb></tscreen>
2649
2650 Receives a PDU from the peer. Returns the number of bytes
2651 read. In nonblocking mode, it is possible that not all of the packet can be
2652 read at once. In this case, the function returns 1. To simplify the
2653 interface, the function is
2654 responsible for managing the size of the buffer. It will be reallocated
2655 if necessary to contain large packages, and will sometimes be moved
2656 around internally by the subsystem when partial packages are read. Before
2657 calling
2658 <tt/cs_get/
2659 for the fist time, the buffer can be initialized to the null pointer,
2660 and the length should also be set to 0 - cs_get will perform a
2661 <tt/malloc/(2)
2662 on the buffer for you. When a full buffer has been read, the size of
2663 the package is returned (which will always be greater than 1). -1
2664 indicates an error condition.
2665
2666 See also the
2667 <tt/cs_more()/
2668 function below.
2669
2670 <tscreen><verb>
2671 int cs_more(COMSTACK handle);
2672 </verb></tscreen>
2673
2674 The <tt/cs_more()/ function should be used in conjunction with
2675 <tt/cs_get/
2676 and
2677 <tt/select/(2).
2678 The <tt/cs_get()/ function will sometimes (notably in the TCP/IP mode) read
2679 more than a single protocol package off the network. When this
2680 happens, the extra package is stored by the subsystem. After calling
2681 <tt/cs_get()/, and before waiting for more input,
2682 You should always call
2683 <tt/cs_more()/
2684 to check if there's a full protocol package already read. If
2685 <tt/cs_more()/
2686 returns 1,
2687 <tt/cs_get()/
2688 can be used to immediately fetch the new package. For the
2689 mOSI
2690 subsystem, the function should always return 0, but if you want your
2691 stuff to be protocol independent, you should use it.
2692
2693 <it>
2694 NOTE: The <tt/cs_more()/
2695 function is required because the
2696 RFC1729-method
2697 does not provide a way of separating individual PDUs, short of
2698 partially decoding the BER. Some other implementations will carefully
2699 nibble at the packet by calling
2700 <tt/read/(2)
2701 several times. This was felt to be too inefficient (or at least
2702 clumsy) - hence the call for this extra function.
2703 </it>
2704
2705 <tscreen><verb>
2706 int cs_look(COMSTACK handle);
2707 </verb></tscreen>
2708
2709 This function is useful when you're operating in nonblocking
2710 mode. Call it when
2711 <tt/select/(2)
2712 tells you there's something happening on the line. It returns one of
2713 the following values:
2714
2715 <descrip>
2716 <tag/CS_NONE/No event is pending. The data found on the line was
2717 not a complete package.
2718 <tag/CS_CONNECT/A response to your connect request has been received. Call
2719 <tt/cs_rcvconnect/
2720 to process the event and to finalize the connection establishment.
2721 <tag/CS_DISCON/The other side has closed the connection (or maybe
2722 sent a disconnect
2723 request - but do we care? Maybe later). Call
2724 <tt/cs_close/ To close your end of the association as well.
2725 <tag/CS_LISTEN/A connect request has been received. Call
2726 <tt/cs_listen/
2727 to process the event.
2728 <tag/CS_DATA/There's data to be found on the line. Call
2729 <tt/cs_get/
2730 to get it.
2731 </descrip>
2732
2733 <it>
2734 NOTE:
2735 You should be aware that even if
2736 <tt/cs_look()/
2737 tells you that there's an event event pending, the corresponding
2738 function may still return and tell you there was nothing to be found.
2739 This means that only part of a package was available for reading. The
2740 same event will show up again, when more data has arrived.
2741 </it>
2742
2743 <tscreen><verb>
2744 int cs_fileno(COMSTACK h);
2745 </verb></tscreen>
2746
2747 Returns the file descriptor of the association. Use this when
2748 file-level operations on the endpoint are required (<tt/select/(2)
2749 operations, specifically).
2750
2751 <sect1>Client Side
2752
2753 <p>
2754 <tscreen><verb>
2755 int cs_connect(COMSTACK handle, void *address);
2756 </verb></tscreen>
2757
2758 Initiate a connection with the target at <tt/address/ (more on
2759 addresses below). The function will return 0 on success, and 1 if
2760 the operation does not complete immediately (this will only
2761 happen on a nonblocking endpoint). In this case, use
2762 <tt/cs_rcvconnect/ to complete the operation, when <tt/select/(2)
2763 reports input pending on the association.
2764
2765 <tscreen><verb>
2766 int cs_rcvconnect(COMSTACK handle);
2767 </verb></tscreen>
2768
2769 Complete a connect operation initiated by <tt/cs_connect()/. It will
2770 return 0 on success; 1 if the operation has not yet completed (in this
2771 case, call the function again later); -1 if an error has occured.
2772
2773 <sect1>Server Side
2774
2775 <p>
2776 To establish a server under the <tt/inetd/ server, you can use
2777
2778 <tscreen><verb>
2779 COMSTACK cs_createbysocket(int socket, CS_TYPE type, int blocking,
2780                               int protocol);
2781 </verb></tscreen>
2782
2783 The <it/socket/ parameter is an established socket (when your
2784 application is invoked from <tt/inetd/, the socket will typically be
2785 0. The following parameters are identical to the ones for
2786 <tt/cs_create/.
2787
2788 <tscreen><verb>
2789 int cs_bind(COMSTACK handle, void *address, int mode)
2790 </verb></tscreen>
2791
2792 Binds a local address to the endpoint. Read about addresses below. The
2793 <tt/mode/ parameter should be either <tt/CS_CLIENT/ or <tt/CS_SERVER/.
2794
2795 <tscreen><verb>
2796 int cs_listen(COMSTACK handle, char *addr, int *addrlen);
2797 </verb></tscreen>
2798
2799 Call this to process incoming events on an endpoint that has been
2800 bound in listening mode. It will return 0 to indicate that the connect
2801 request has been received, 1 to signal a partial reception, and -1 to
2802 indicate an error condition.
2803
2804 <tscreen><verb>
2805 COMSTACK cs_accept(COMSTACK handle);
2806 </verb></tscreen>
2807
2808 This finalises the server-side association establishment, after
2809 cs_listen has completed successfully. It returns a new connection
2810 endpoint, which represents the new association. The application will
2811 typically wish to fork off a process to handle the association at this
2812 point, and continue listen for new connections on the old <tt/handle/.
2813
2814 You can use the call
2815
2816 <tscreen><verb>
2817 char *cs_addrstr(COMSTACK);
2818 </verb></tscreen>
2819
2820 on an established connection to retrieve the hostname of the remote host.
2821
2822 <it>NOTE: You may need to use this function with some care if your
2823 name server service is slow or unreliable</it>
2824
2825 <sect1>Addresses
2826
2827 <p>
2828 The low-level format of the addresses are different depending on the
2829 mode of communication you have chosen. A function is provided by each
2830 of the lower layers to map a user-friendly string-form address to the
2831 binary form required by the lower layers.
2832
2833 <tscreen><verb>
2834 struct sockaddr_in *tcpip_strtoaddr(char *str);
2835
2836 struct netbuf *mosi_strtoaddr(char *str);
2837 </verb></tscreen>
2838
2839 The format for TCP/IP addresses is straightforward:
2840
2841 <tscreen><verb>
2842 <host> &lsqb; ':' <portnum> &rsqb;
2843 </verb></tscreen>
2844
2845 The <tt/hostname/ can be either a domain name or an IP address. The
2846 port number, if omitted, defaults to 210.
2847
2848 For OSI, the format is
2849
2850 <tscreen><verb>
2851 &lsqb; <t-selector> '/' &rsqb; <host> &lsqb; ':' <port> &rsqb;
2852 </verb></tscreen>
2853
2854 The transport selector is given as an even number of hex digits.
2855
2856 You'll note that the address format for the OSI mode are just a subset
2857 of full presentation addresses. We use presentation addresses because
2858 xtimosi doesn't, in itself, allow access to the X.500 Directory
2859 service. We use a limited form, because we haven't yet come across an
2860 implementation that used more of the elements of a full p-address. It
2861 is a fairly simple matter to add the rest of the elements to the
2862 address format as needed, however: Xtimosi <it/does/ support the full
2863 P-address structure.
2864
2865 In both transport modes, the special hostname &dquot;@&dquot; is mapped
2866 to any local address (the manifest constant INADDR_ANY). It is used
2867 to establish local listening endpoints in the server role.
2868
2869 When a connection has been established, you can use
2870
2871 <tscreen><verb>
2872 char cs_addrstr(COMSTACK h);
2873 </verb></tscreen>
2874
2875 to retrieve the host name of the peer system. The function returns a pointer
2876 to a static area, which is overwritten on the next call to the function.
2877
2878 <it>
2879 NOTE: We have left the issue of X.500 name-to-address mapping open, for the
2880 moment. It would be a simple matter to provide a table-based mapping,
2881 if desired. Alternately, we could use the X.500 client-function that
2882 is provided with the ISODE (although this would defeat some of the
2883 purpose of using ThinOSI in the first place. We have been told that it
2884 should be within the realm of the possible to implement a lightweight
2885 implementation of the necessary X.500 client capabilities on top of
2886 ThinOSI. This would be the ideal solution, we feel. On the other hand, it
2887 still remains to be seen just what role the Directory will play in a world
2888 populated by ThinOSI and other pragmatic solutions.
2889 </it>
2890
2891 <sect1>Diagnostics
2892
2893 <p>
2894 All functions return -1 if an error occurs. Typically, the functions
2895 will return 0 on success, but the data exchange functions
2896 (<tt/cs_get/, <tt/cs_put/, <tt/cs_more/)
2897 follow special rules. Consult their descriptions.
2898
2899 When a function (including the data exchange functions) reports an
2900 error condition,
2901 use the function
2902 <tt/cs_errno()/
2903 to determine the cause of the
2904 problem. The function
2905
2906 <tscreen><verb>
2907 void cs_perror(COMSTACK handle char *message);
2908 </verb></tscreen>
2909
2910 works like
2911 <tt/perror/(2)
2912 and prints the
2913 <tt/message/
2914 argument, along with a system message, to
2915 <tt/stderr/.
2916 Use the character array
2917
2918 <tscreen><verb>
2919 extern const char *cs_errlist&lsqb;&rsqb;;
2920 </verb></tscreen>
2921
2922 to get hold of the message, if you want to process it differently.
2923 The function
2924
2925 <tscreen><verb>
2926 const char *cs_stackerr(COMSTACK handle);
2927 </verb></tscreen>
2928
2929 Returns an error message from the lower layer, if one has been
2930 provided.
2931
2932 <sect1>Enabling OSI Communication
2933
2934 <sect2>Installing Xtimosi
2935 <p>
2936 Although you will have to download Peter Furniss' XTI/mOSI
2937 implementation for yourself, we've tried to make the integration as
2938 simple as possible.
2939
2940 The latest version of xtimosi will generally be under
2941
2942 <tscreen><verb>
2943 ftp://pluto.ulcc.ac.uk/ulcc/thinosi/xtimosi/
2944 </verb></tscreen>
2945
2946 When you have downloaded and unpacked the archive, it will (we assume)
2947 have created a directory called <tt/xtimosi/. We suggest that you place
2948 this directory <it/in the same directory/ where you unpacked the
2949 <bf/YAZ/
2950 distribution. This way, you shouldn't have to fiddle with the
2951 makefiles of <tt/YAZ/ beyond uncommenting a few lines.
2952
2953 Go to <tt>xtimosi/src</tt>, and type &dquot;<tt/make libmosi.a/&dquot;.
2954 This should generally
2955 create the library, ready to use.
2956
2957 <bf/CAVEAT/
2958
2959 <it>
2960 The currently available release of xtimosi has some inherent
2961 problems that make it disfunction on certain platforms - eg. the
2962 Digital OSF/1 workstations. It is supposedly primarily a
2963 compiler problem, and we hope to see a release that is generally
2964 portable. While we can't guarantee that it can be brought to work
2965 on your platform, we'll be happy to talk to you about problems
2966 that you might see, and relay information to the author of the
2967 software. There are some signs that the <bf/gcc/ compiler is more
2968 likely to produce a fully functional library, but this hasn't
2969 been verified (we think that the problem is limited to the use
2970 of hexadecimal escape-codes used in strings, which are silently
2971 ignored by some compilers).
2972 </it>
2973
2974 <it>
2975 A problem has been encountered in the communication with
2976 ISODE-based applications. If the ISODE presentation-user calls
2977 <tt/PReadRequest()/ with a timeout value different from <tt/OK/ or <tt/NOTOK/,
2978 he will get an immediate TIMEOUT abort when receiving large (&gt;2041
2979 bytes, which is the SPDU-size that the ISODE likes to work with) packages
2980 from an xtimosi-based implementation (probably most
2981 other implementations as well, in fact). It seems to be a flaw in the
2982 ISODE API, and the workaround (for ISODE users) is to either not
2983 use an explicit timeout (switching to either blocking or
2984 nonblocking mode), or to check that the timer really has expired
2985 before closing the connection.
2986 </it>
2987
2988 The next step in the installation is to modify the makefile in the toplevel
2989 <bf/YAZ/
2990 directory. The place to change is in the top of the file, and is
2991 clearly marked with a comment.
2992
2993 Now run <tt/make/ in the <bf/YAZ/ toplevel directory (do a
2994 &dquot;<tt/make clean/&dquot; first, if the
2995 system has been previously made without OSI support). Use the <bf/YAZ/
2996 <bf/ztest/
2997 and <bf/client/ demo programs to verify that OSI communication works OK. Then,
2998 you can go ahead and try to talk to other implementations.
2999
3000 <it>
3001 NOTE: Our interoperability experience is limited to version
3002 7 of the Nordic SR-Nett package, which has had several
3003 protocol errors fixed from the earlier releases. If you have
3004 problems or successes in interoperating with other
3005 implementations, we'd be glad to hear about it, or to help
3006 you make things work, as our resources allow.
3007 </it>
3008
3009 If you write your own applications based on <bf/YAZ/, and you wish to
3010 include OSI support, the procedure is equally simple. You should
3011 include the <tt/xmosi.h/ header file in addition to <tt/comstack.h/.
3012 <tt/xmosi.h/
3013 will define the manifest constant <tt/mosi_type/, which you should pass
3014 to the <tt/cs_create()/ function. In
3015 addition, you should use the function <tt/mosi_strtoaddr()/ rather than
3016 <tt/tcpip_strtoaddr()/ when you need to prepare an address.
3017
3018 When you link your application, you should include (after the
3019 <tt/libyaz.a/
3020 library) the <tt/libmosi.a/ library, and the <tt/librfc.a/ library
3021 provided with
3022 <bf/YAZ/ (for OSI transport).
3023
3024 As always, it can be very useful, if not essential, to have a look at the
3025 example applications
3026 to see how things are done.
3027
3028 <sect2>OSI Transport
3029
3030 <p>
3031 Xtimosi requires an implementation of the OSI transport service under
3032 the X/OPEN XTI API. We provide an implementation of the RFC1006
3033 encapsulation of OSI/TP0 in TCP/IP (through the Berkeley Sockets API),
3034 as an independent part of <bf/YAZ/ (it's found under the <tt/rfc1006/
3035 directory). If you have access to an OSI transport provider under XTI,
3036 you should be able to make that work too, although it may require
3037 tinkering with the <tt/mosi_strtoaddr()/ function.
3038
3039 <sect2>Presentation Context Management
3040
3041 <p>
3042 To simplify the implementation, we use Peter Furniss' alternative (PRF)
3043 option format
3044 for the Control of the presentation negotiation phase. This format
3045 is enabled by default when you
3046 compile xtimosi.
3047
3048 The current version of <bf/YAZ/ does <it/not/ support presentation-layer
3049 negotiation of response record formats. The primary reason is that we
3050 have had access to no other SR or Z39.50 implementations over OSI that
3051 used this
3052 method. Secondarily, we believe that the EXPLAIN facility is a superior
3053 mechanism for relaying target capabilities in this respect. This is not to
3054 say that we have no intentions of supporting presentation context
3055 negotiation - we have just hitherto given it a lower priority than other
3056 aspects of the protocol.
3057
3058 One thing is certain: The addition of this capability to <bf/YAZ/ should
3059 have only a minimal impact on existing applications, and on the
3060 interface to the software in general. Most likely, we will add an extra
3061 layer of interface to the processing of EXPLAIN records, which will
3062 convert back and forth between <tt/oident/ records (see section
3063 <ref id="oid" name="Object Identifiers">) and direct or indirect
3064 references, given the current association setup. Implementations based
3065 on any of the higher-level interfaces will most likely not have to be
3066 changed at all.
3067
3068 <sect1>Summary and Synopsis
3069
3070 <p>
3071 <tscreen><verb>
3072 #include <comstack.h>
3073
3074 #include <tcpip.h>      /* this is for TCP/IP support   */
3075 #include <xmosi.h>      /* and this is for mOSI support */
3076
3077 COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
3078
3079 COMSTACK cs_createbysocket(int s, CS_TYPE type, int blocking,
3080                               int protocol);
3081
3082 int cs_bind(COMSTACK handle, int mode);
3083
3084 int cs_connect(COMSTACK handle, void *address);
3085
3086 int cs_rcvconnect(COMSTACK handle);
3087
3088 int cs_listen(COMSTACK handle);
3089
3090 COMSTACK cs_accept(COMSTACK handle);
3091
3092 int cs_put(COMSTACK handle, char *buf, int len);
3093
3094 int cs_get(COMSTACK handle, char **buf, int *size);
3095
3096 int cs_more(COMSTACK handle);
3097
3098 int cs_close(COMSTACK handle);
3099
3100 int cs_look(COMSTACK handle);
3101
3102 struct sockaddr_in *tcpip_strtoaddr(char *str);
3103
3104 struct netbuf *mosi_strtoaddr(char *str);
3105
3106 extern int cs_errno;
3107
3108 void cs_perror(COMSTACK handle char *message);
3109
3110 const char *cs_stackerr(COMSTACK handle);
3111
3112 extern const char *cs_errlist[];
3113 </verb></tscreen>
3114
3115 <sect>Making an IR Interface for Your Database with YAZ<label id="server">
3116
3117 <sect1>Introduction
3118
3119 <p>
3120 <it>
3121 NOTE: If you aren't into documentation, a good way to learn how the
3122 backend interface works is to look at the backend.h file. Then,
3123 look at the small dummy-server in server/ztest.c. Finally, you can
3124 have a look at the seshigh.c file, which is where most of the
3125 logic of the frontend server is located. The backend.h file also
3126 makes a good reference, once you've chewed your way through
3127 the prose of this file.
3128 </it>
3129
3130 If you have a database system that you would like to make available by
3131 means of Z39.50/SR, <bf/YAZ/ basically offers your two options. You
3132 can use the APIs provided by the <bf/ASN/, <bf/ODR/, and <bf/COMSTACK/
3133 modules to
3134 create and decode PDUs, and exchange them with a client. Using this
3135 low-level interface gives you access to all fields and options of the
3136 protocol, and you can construct your server as close to your existing
3137 database as you like. It is also a fairly involved process, requiring
3138 you to set up an event-handling mechanism, protocol state machine,
3139 etc. To simplify server implementation, we have implemented a compact
3140 and simple, but reasonably full-functioned server-frontend that will
3141 handle most of the protocol mechanics, while leaving you to
3142 concentrate on your database interface.
3143
3144 <it>
3145 NOTE: The backend interface was designed in anticipation of a specific
3146 integration task, while still attempting to achieve some degree of
3147 generality. We realise fully that there are points where the
3148 interface can be improved significantly. If you have specific
3149 functions or parameters that you think could be useful, send us a
3150 mail (or better, sign on to the mailing list referred to in the
3151 toplevel README file). We will try to fit good suggestions into future
3152 releases, to the extent that it can be done without requiring
3153 too many structural changes in existing applications.
3154 </it>
3155
3156 <sect1>The Database Frontend
3157
3158 <p>
3159 We refer to this software as a generic database frontend. Your
3160 database system is the <it/backend database/, and the interface between
3161 the two is called the <it/backend API/. The backend API consists of a
3162 small number of function prototypes and structure definitions. You are
3163 required to provide the <bf/main()/ routine for the server (which can be
3164 quite simple), as well as functions to match each of the prototypes.
3165 The interface functions that you write can use any mechanism you like
3166 to communicate with your database system: You might link the whole
3167 thing together with your database application and access it by
3168 function calls; you might use IPC to talk to a database server
3169 somewhere; or you might link with third-party software that handles
3170 the communication for you (like a commercial database client library).
3171 At any rate, the functions will perform the tasks of:
3172
3173 <itemize>
3174 <item>Initialization.
3175 <item>Searching.
3176 <item>Fetching records.
3177 <item>Scanning the database index (if you wish to implement SCAN).
3178 </itemize>
3179
3180 (more functions will be added in time to support as much of
3181 Z39.50-1995 as possible).
3182
3183 Because the model where pipes or sockets are used to access the backend
3184 database is a fairly common one, we have added a mechanism that allows this
3185 communication to take place asynchronously. In this mode, the frontend
3186 server doesn't have to block while the backend database is processing
3187 a request, but can wait for additional PDUs from the client.
3188
3189 <sect1>The Backend API
3190
3191 <p>
3192 The headers files that you need to use the interface are in the
3193 include/ directory. They are called <tt/statserv.h/ and <tt/backend.h/. They
3194 will include other files from the <tt/include/ directory, so you'll
3195 probably want to use the -I option of your compiler to tell it where
3196 to find the files. When you run <tt/make/ in the toplevel <bf/YAZ/ directory,
3197 everything you need to create your server is put the lib/libyaz.a
3198 library. If you want OSI as well, you'll also need to link in the
3199 <tt/libmosi.a/ library from the xtimosi distribution (see the mosi.txt
3200 file), a well as the <tt>lib/librfc.a</tt> library (to provide OSI transport
3201 over RFC1006/TCP).
3202
3203 <sect1>Your main() Routine
3204
3205 <p>
3206 As mentioned, your <bf/main()/ routine can be quite brief. If you want to
3207 initialize global parameters, or read global configuration tables,
3208 this is the place to do it. At the end of the routine, you should call
3209 the function
3210
3211 <tscreen><verb>int statserv_main(int argc, char **argv);</verb></tscreen>
3212
3213 <bf/Statserv_main/ will establish listening sockets according to the
3214 parameters given. When connection requests are received, the event
3215 handler will typically <bf/fork()/ to handle the new request. If you do use
3216 global variables, you should be aware, then, that these cannot be
3217 shared between associations, unless you explicitly disallow forking by
3218 command line parameters (we advise against this for any purposes
3219 except debugging, as a crash or hang in the server process will affect
3220 all users currently signed on to the server).
3221
3222 The server provides a mechanism for controlling some of its behavior
3223 without using command-line options. The function
3224
3225 <tscreen><verb>
3226 statserv_options_block *statserv_getcontrol(void);
3227 </verb></tscreen>
3228
3229 Will return a pointer to a <tt/struct statserv_options_block/ describing
3230 the current default settings of the server. The structure contains
3231 these elements:
3232
3233 <descrip>
3234 <tag/int dynamic/A boolean value, which determines whether the server
3235 will fork on each incoming request (TRUE), or not (FALSE). Default is
3236 TRUE.
3237 <tag/int loglevel/Set this by ORing the constants defined in include/log.h.
3238 <tag/char logfile&lsqb;ODR_MAXNAME+1&rsqb;/File for diagnostic output
3239 (&dquot;&dquot;: stderr).
3240 <tag/char apdufile&lsqb;ODR_MAXNAME+1&rsqb;/Name of file for logging incoming and
3241 outgoing APDUs (&dquot;&dquot;: don't log APDUs, &dquot;-&dquot;: <tt/stderr/).
3242 <tag/char default_listen&lsqb;1024&rsqb;/Same form as the command-line
3243 specification of listener address. &dquot;&dquot;: no default listener address.
3244 Default is to listen at &dquot;tcp:@:9999&dquot;. You can only
3245 specify one default listener address in this fashion.
3246 <tag/enum oid_proto default_proto;/Either <tt/PROTO_SR/ or <tt/PROTO_Z3950/.
3247 Default is <tt/PROTO_Z39_50/.
3248 <tag/int idle_timeout;/Maximum session idletime, in minutes. Zero indicates
3249 no (infinite) timeout. Default is 120 minutes.
3250 <tag/int maxrecordsize;/Maximum permissible record (message) size. Default
3251 is 1Mb. This amount of memory will only be allocated if a client requests a
3252 very large amount of records in one operation (or a big record). Set it
3253 to a lower number
3254 if you are worried about resource consumption on your host system.
3255 <tag/char configname&lsqb;ODR_MAXNAME+1&rsqb;/Passed to the backend when a
3256 new connection is received.
3257 <tag/char setuid&lsqb;ODR_MAXNAME+1&rsqb;/Set user id to the user specified,
3258 after binding the listener addresses.
3259 </descrip>
3260
3261 The pointer returned by <tt/statserv_getcontrol/ points to a static area.
3262 You are allowed to change the contents of the structure, but the
3263 changes will not take effect before you call
3264
3265 <tscreen><verb>
3266 void statserv_setcontrol(statserv_options_block *block);
3267 </verb></tscreen>
3268
3269 Note that you should generally update this structure <it/before/ calling
3270 <tt/statserv_main()/.
3271
3272 <sect1>The Backend Functions
3273
3274 <p>
3275 For each service of the protocol, the backend interface declares one or
3276 two functions. You are required to provide implementations of the
3277 functions representing the services that you wish to implement.
3278
3279 <tscreen><verb>bend_initresult *bend_init(bend_initrequest *r);</verb></tscreen>
3280
3281 This function is called once for each new connection request, after
3282 a new process has been forked, and an initRequest has been received
3283 from the client. The parameter and result structures are defined as
3284
3285 <tscreen>
3286 <verb>
3287 typedef struct bend_initrequest
3288 {
3289     char *configname;
3290 } bend_initrequest;
3291
3292 typedef struct bend_initresult
3293 {
3294     int errcode;       /* 0==OK */
3295     char *errstring;   /* system error string or NULL */
3296     void *handle;      /* private handle to the backend module */
3297 } bend_initresult;
3298 </verb>
3299 </tscreen>
3300
3301 The <tt/configname/ of <tt/bend_initrequest/ is currently always set to
3302 &dquot;default-config&dquot;. We haven't had use for putting anything special in
3303 the initrequest yet, but something might go there if the need arises
3304 (account/password info would be obvious).
3305
3306 In general, the server frontend expects that the <tt/bend_*result/
3307 pointer that you return is valid at least until the next call to a
3308 <tt/bend_* function/. This applies to all of the functions described
3309 herein. The parameter structure passed to you in the call belongs to
3310 the server frontend, and you should not make assumptions about its
3311 contents after the current function call has completed. In other
3312 words, if you want to retain any of the contents of a request
3313 structure, you should copy them.
3314
3315 The <tt/errcode/ should be zero if the initialization of the backend went
3316 well. Any other value will be interpreted as an error. The
3317 <tt/errstring/ isn't used in the current version, but one option
3318 would be to stick it
3319 in the initResponse as a VisibleString. The <tt/handle/ is the most
3320 important parameter. It should be set to some value that uniquely
3321 identifies the current session to the backend implementation. It is
3322 used by the frontend server in any future calls to a backend function.
3323 The typical use is to set it to point to a dynamically allocated state
3324 structure that is private to your backend module.
3325
3326 <tscreen>
3327 <verb>
3328 bend_searchresult *bend_search(void *handle, bend_searchrequest *r,
3329                                int *fd);
3330 bend_searchresult *bend_searchresponse(void *handle);
3331
3332 typedef struct bend_searchrequest
3333 {
3334     char *setname;       /* name to give to this set */
3335     int replace_set;     /* replace set, if it already exists */
3336     int num_bases;       /* number of databases in list */
3337     char **basenames;    /* databases to search */
3338     Z_Query *query;      /* query structure */
3339 } bend_searchrequest;
3340
3341 typedef struct bend_searchresult
3342 {
3343     int hits;            /* number of hits */
3344     int errcode;         /* 0==OK */
3345     char *errstring;     /* system error string or NULL */
3346 } bend_searchresult;
3347 </verb>
3348 </tscreen>
3349
3350 The first thing to notice about the search request interface (as well
3351 as all of the following requests), is that it consists of two separate
3352 functions. The idea is to provide a simple facility for
3353 asynchronous communication with the backend server. When a
3354 searchrequest comes in, the server frontend will fill out the
3355 <tt/bend_searchrequest/ tructure, and call the <tt/bend_search
3356 function/. The <tt/fd/
3357 argument will point to an integer variable. If you are able to do
3358 asynchronous I/O with your database server, you should set *<tt/fd/ to the
3359 file descriptor you use for the communication, and return a null
3360 pointer. The server frontend will then <tt/select()/ on the *<tt/fd/,
3361 and will call
3362 <tt/bend_searchresult/ when it sees that data is available. If you don't
3363 support asynchronous I/O, you should return a pointer to the
3364 <tt/bend_searchresult/ immediately, and leave *<tt/fd/ untouched. This
3365 construction is common to all of the <tt/bend_/ functions (except
3366 <tt/bend_init/). Note that you can choose to support this facility in none,
3367 any, or all of the <tt/bend_/ functions, and you can respond
3368 differently on each request at run-time. The server frontend will
3369 adapt accordingly.
3370
3371 The <tt/bend_searchrequest/ is a fairly close approximation of a protocol
3372 searchRequest PDU. The <tt/setname/ is the resultSetName from the protocol. You
3373 are required to establish a mapping between the set name and whatever
3374 your backend database likes to use. Similarly, the <tt/replace_set/ is a
3375 boolean value corresponding to the resultSetIndicator field in the
3376 protocol. <tt>Num_bases/basenames</tt> is a length of/array of character
3377 pointers to the database names provided by the client. The <tt/query/ is the
3378 full query structure as defined in the protocol ASN.1 specification.
3379 It can be either of the possible query types, and it's up to you to
3380 determine if you can handle the provided query type. Rather than
3381 reproduce the C interface here, we'll refer you to the structure
3382 definitions in the file <tt>include/proto.h</tt>. If you want to look at the
3383 attributeSetId OID of the RPN query, you can either match it against
3384 your own internal tables, or you can use the <tt/oid_getentbyoid/ function
3385 provided by <bf/YAZ/.
3386
3387 The result structure contains a number of hits, and an
3388 <tt>errcode/errstring</tt> pair. If an error occurs during the search, or if
3389 you're unhappy with the request, you should set the errcode to a value
3390 from the BIB-1 diagnostic set. The value will then be returned to the
3391 user in a nonsurrogate diagnostic record in the response. The
3392 <tt/errstring/, if provided, will go in the addinfo field. Look at the
3393 protocol definition for the defined error codes, and the suggested
3394 uses of the addinfo field.
3395
3396 <tscreen>
3397 <verb>
3398 bend_fetchresult *bend_fetch(void *handle, bend_fetchrequest *r,
3399                              int *fd);
3400 bend_fetchresult *bend_fetchresponse(void *handle);
3401
3402 typedef struct bend_fetchrequest
3403 {
3404     char *setname;       /* set name */
3405     int number;          /* record number */
3406     oid_value format;
3407 } bend_fetchrequest;
3408
3409 typedef struct bend_fetchresult
3410 {
3411     char *basename;      /* name of database that provided record */
3412     int len;             /* length of record */
3413     char *record;        /* record */
3414     int last_in_set;     /* is it?  */
3415     oid_value format;
3416     int errcode;         /* 0==success */
3417     char *errstring;     /* system error string or NULL */
3418 } bend_fetchresult;
3419 </verb>
3420 </tscreen>
3421
3422 <it>
3423 NOTE: The <tt/bend_fetchresponse()/ function is not yet supported
3424 in this version of the software. Your implementation of <tt/bend_fetch()/
3425 should always return a pointer to a <tt/bend_fetchresult/.
3426 </it>
3427
3428 The frontend server calls <tt/bend_fetch/ when it needs database records to
3429 fulfill a searchRequest or a presentRequest. The <tt/setname/ is simply the
3430 name of the result set that holds the reference to the desired record.
3431 The <tt/number/ is the offset into the set (with 1 being the first record
3432 in the set). The <tt/format/ field is the record format requested by the
3433 client (See section <ref id="oid" name="Object Identifiers">). The value
3434 <tt/VAL_NONE/ indicates that the client did not request a specific format.
3435 The <tt/stream/ argument is an <bf/ODR/ stream which should be used for
3436 allocating space for structured data records. The stream will be reset when
3437 all records have been assembled, and the response package has been transmitted.
3438 For unstructured data, the backend is responsible for maintaining a static
3439 or dynamic buffer for the record between calls.
3440
3441 In the result structure, the <tt/basename/ is the name of the
3442 database that holds the
3443 record. <tt/Len/ is the length of the record returned, in bytes, and
3444 <tt/record/
3445 is a pointer to the record. <tt/Last_in_set/ should be nonzero only if the
3446 record returned is the last one in the given result set. <tt/Errcode/ and
3447 <tt/errstring/, if given, will currently be interpreted as a global error
3448 pertaining to the set, and will be returned in a
3449 nonSurrogateDiagnostic.
3450
3451 <it>NOTE: This is silly. Add a flag to say which is which.</it>
3452
3453 If the <tt/len/ field has the value -1, then <tt/record/ is assumed to point
3454 to a constructed data type. The <tt/format/ field will be used to determine
3455 which encoder should be used to serialize the data.
3456
3457 <it>
3458 NOTE: If your backend generates structured records, it should use
3459 <tt/odr_malloc()/ on the provided stream for allocating data: This allows
3460 the frontend server to keep track of the record sizes.
3461 </it>
3462
3463 The <tt/format/ field is mapped to an object identifier in the direct
3464 reference of the resulting EXTERNAL representation of the record.
3465
3466 <it>NOTE: The current version of <bf/YAZ/ only supports the direct reference
3467 mode.</it>
3468
3469 <tscreen>
3470 <verb>
3471 bend_deleteresult *bend_delete(void *handle, bend_deleterequest *r,
3472                                int *fd);
3473 bend_deleteresult *bend_deleteresponse(void *handle);
3474
3475 typedef struct bend_deleterequest
3476 {
3477     char *setname;
3478 } bend_deleterequest;
3479
3480 typedef struct bend_deleteresult
3481 {
3482     int errcode;         /* 0==success */
3483     char *errstring;     /* system error string or NULL */
3484 } bend_deleteresult;
3485 </verb>
3486 </tscreen>
3487
3488 <it>
3489 NOTE: The &dquot;delete&dquot; function is not yet supported
3490 in this version of the software.
3491 </it>
3492
3493 <it>
3494 NOTE: The delete set function definition is rather primitive, mostly
3495 because we
3496 have had no practical need for it as of yet. If someone wants
3497 to provide a full delete service, we'd be happy to add the
3498 extra parameters that are required. Are there clients out there
3499 that will actually delete sets they no longer need?
3500 </it>
3501
3502 <tscreen>
3503 <verb>
3504 bend_scanresult *bend_scan(void *handle, bend_scanrequest *r,
3505     int *fd);
3506 bend_scanresult *bend_scanresponse(void *handle);
3507
3508 typedef struct bend_scanrequest
3509 {
3510     int num_bases;      /* number of elements in databaselist */
3511     char **basenames;   /* databases to search */
3512     Z_AttributesPlusTerm *term;
3513     int term_position;  /* desired index of term in result list */
3514     int num_entries;    /* number of entries requested */
3515 } bend_scanrequest;
3516
3517 typedef struct bend_scanresult
3518 {
3519     int num_entries;
3520     struct scan_entry
3521     {
3522         char *term;
3523         int occurrences;
3524     } *entries;
3525     int term_position;
3526     enum
3527     {
3528         BEND_SCAN_SUCCESS,
3529         BEND_SCAN_PARTIAL
3530     } status;
3531     int errcode;
3532     char *errstring;
3533 } bend_scanresult;
3534 </verb>
3535 </tscreen>
3536
3537 <it>
3538 NOTE: The <tt/bend_scanresponse()/ function is not yet supported
3539 in this version of the software. Your implementation of <tt/bend_scan()/
3540 should always return a pointer to a <tt/bend_scanresult/.
3541 </it>
3542
3543 <sect1>Application Invocation
3544
3545 <p>
3546 The finished application has the following
3547 invocation syntax (by way of <tt/statserv_main()/):
3548
3549 <tscreen> <verb>
3550 appname &lsqb;-szSu -a apdufile -l logfile -v loglevel&rsqb;
3551 &lsqb;listener ...&rsqb;
3552 </verb> </tscreen>
3553
3554 The options are
3555
3556 <descrip>
3557 <tag/-a/APDU file. Specify a file for dumping PDUs (for diagnostic purposes).
3558 The special name &dquot;-&dquot; sends output to <tt/stderr/.
3559
3560 <tag/-S/Don't fork on connection requests. This is good for debugging, but
3561 not recommended for real operation: Although the server is
3562 asynchronous and non-blocking, it can be nice to keep a software
3563 malfunction (okay then, a crash) from affecting all current users.
3564
3565 <tag/-s/Use the SR protocol.
3566
3567 <tag/-z/Use the Z39.50 protocol (default). These two options complement
3568 eachother. You can use both multiple times on the same command
3569 line, between listener-specifications (see below). This way, you
3570 can set up the server to listen for connections in both protocols
3571 concurrently, on different local ports.
3572
3573 <tag/-l/The logfile.
3574
3575 <tag/-v/The log level. Use a comma-separated list of members of the set
3576 {fatal,debug,warn,log,all,none}.
3577 <tag/-u/Set user ID. Sets the real UID of the server process to that of the
3578 given user. It's useful if you aren't comfortable with having the
3579 server run as root, but you need to start it as such to bind a
3580 privileged port.
3581
3582 <tag/-w/Working directory.
3583 <tag/-i/Use this when running from the <tt/inetd/ server.
3584
3585 <tag/-t/Idle session timeout, in minutes.
3586
3587 <tag/-k/Maximum record size/message size, in kilobytes.
3588
3589 </descrip>
3590
3591 A listener specification consists of a transport mode followed by a
3592 colon (:) followed by a listener address. The transport mode is
3593 either <tt/osi/ or <tt/tcp/.
3594
3595 For TCP, an address has the form
3596
3597 <tscreen><verb>
3598 hostname | IP-number &lsqb;: portnumber&rsqb;
3599 </verb></tscreen>
3600
3601 The port number defaults to 210 (standard Z39.50 port).
3602
3603 For osi, the address form is
3604
3605 <tscreen><verb>
3606 &lsqb;t-selector /&rsqb; hostname | IP-number &lsqb;: portnumber&rsqb;
3607 </verb></tscreen>
3608
3609 The transport selector is given as a string of hex digits (with an even
3610 number of digits). The default port number is 102 (RFC1006 port).
3611
3612 Examples
3613
3614 <tscreen>
3615 <verb>
3616 tcp:dranet.dra.com
3617
3618 osi:0402/dbserver.osiworld.com:3000
3619 </verb>
3620 </tscreen>
3621
3622 In both cases, the special hostname &dquot;@&dquot; is mapped to
3623 the address INADDR_ANY, which causes the server to listen on any local
3624 interface. To start the server listening on the registered ports for
3625 Z39.50 and SR over OSI/RFC1006, and to drop root privileges once the
3626 ports are bound, execute the server like this (from a root shell):
3627
3628 <tscreen><verb>
3629 my-server -u daemon tcp:@ -s osi:@
3630 </verb></tscreen>
3631
3632 You can replace <tt/daemon/ with another user, eg. your own account, or
3633 a dedicated IR server account. <tt/my-server/ should be the name of your
3634 server application. You can test the procedure with the <tt/ztest/
3635 application.
3636
3637 <sect1>Summary and Synopsis
3638
3639 <p>
3640 <tscreen><verb>
3641 #include <backend.h>
3642
3643 bend_initresult *bend_init(bend_initrequest *r);
3644
3645 bend_searchresult *bend_search(void *handle, bend_searchrequest *r,
3646                                  int *fd);
3647
3648 bend_searchresult *bend_searchresponse(void *handle);
3649
3650 bend_fetchresult *bend_fetch(void *handle, bend_fetchrequest *r,
3651                                int *fd);
3652
3653 bend_fetchresult *bend_fetchresponse(void *handle);
3654
3655 bend_scanresult *bend_scan(void *handle, bend_scanrequest *r, int *fd);
3656
3657 bend_scanresult *bend_scanresponse(void *handle);
3658
3659 bend_deleteresult *bend_delete(void *handle, bend_deleterequest *r,
3660                                   int *fd);
3661
3662 bend_deleteresult *bend_deleteresponse(void *handle);
3663
3664 void bend_close(void *handle);
3665 </verb></tscreen>
3666
3667 <sect>Future Directions
3668
3669 <p>
3670 The software has been
3671 successfully ported to the Mac as well as Windows NT/95 - we'd like to
3672 test those ports better and make sure they work as they should.
3673
3674 We have a new and better version of the frontend server on the drawing
3675 board. Resources and external commitments will govern when we'll be
3676 able to do something real with it. Fetures should include greater
3677 flexibility, greter support for access/resource control, and easy
3678 support for Explain (possibly with Zebra as an extra database engine).
3679
3680 We now support all PDUs of Z39.50-1995. If there is one of the
3681 supporting structures that you need but can't find in the prt*.h
3682 files, send us a note; it may be on its way.
3683
3684 The 'retrieval' module needs to be finalized and documented. We think
3685 it can form a useful resource for people dealing with complex record
3686 structures, but for now, you'll mostly have to chew through the code
3687 yourself to make use of it. Not acceptable.
3688
3689 Other than that, YAZ generally moves in the directions which appear to
3690 make the most people happy (including ourselves, as prime users of the
3691 software). If there's something you'd like to see in here, then drop
3692 us a note and let's see what we can come up with.
3693
3694 <sect>License
3695
3696 <sect1>Index Data Copyright
3697
3698 <p>
3699 Copyright &copy; 1995-2000 Index Data.
3700
3701 Permission to use, copy, modify, distribute, and sell this software and
3702 its documentation, in whole or in part, for any purpose, is hereby granted,
3703 provided that:
3704
3705 1. This copyright and permission notice appear in all copies of the
3706 software and its documentation. Notices of copyright or attribution
3707 which appear at the beginning of any file must remain unchanged.
3708
3709 2. The names of Index Data or the individual authors may not be used to
3710 endorse or promote products derived from this software without specific
3711 prior written permission.
3712
3713 THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
3714 EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
3715 WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
3716 IN NO EVENT SHALL INDEX DATA BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
3717 INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
3718 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR
3719 NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
3720 LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
3721 OF THIS SOFTWARE.
3722
3723 <sect1>Additional Copyright Statements
3724
3725 <p>
3726 The optional CCL query language interpreter is covered by the following
3727 license:
3728
3729 Copyright &copy; 1995, the EUROPAGATE consortium (see below).
3730
3731 The EUROPAGATE consortium members are:
3732
3733    University College Dublin
3734    Danmarks Teknologiske Videnscenter
3735    An Chomhairle Leabharlanna
3736    Consejo Superior de Investigaciones Cientificas
3737
3738 Permission to use, copy, modify, distribute, and sell this software and
3739 its documentation, in whole or in part, for any purpose, is hereby granted,
3740 provided that:
3741
3742 1. This copyright and permission notice appear in all copies of the
3743 software and its documentation. Notices of copyright or attribution
3744 which appear at the beginning of any file must remain unchanged.
3745
3746 2. The names of EUROPAGATE or the project partners may not be used to
3747 endorse or promote products derived from this software without specific
3748 prior written permission.
3749
3750 3. Users of this software (implementors and gateway operators) agree to
3751 inform the EUROPAGATE consortium of their use of the software. This
3752 information will be used to evaluate the EUROPAGATE project and the
3753 software, and to plan further developments. The consortium may use
3754 the information in later publications.
3755
3756 4. Users of this software agree to make their best efforts, when
3757 documenting their use of the software, to acknowledge the EUROPAGATE
3758 consortium, and the role played by the software in their work.
3759
3760 THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
3761 EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
3762 WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
3763 IN NO EVENT SHALL THE EUROPAGATE CONSORTIUM OR ITS MEMBERS BE LIABLE
3764 FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF
3765 ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
3766 OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND
3767 ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
3768 USE OR PERFORMANCE OF THIS SOFTWARE.
3769
3770 <sect>About Index Data
3771
3772 <p>
3773 Index Data is a consulting and software-development enterprise that
3774 specialises in library and information management systems. Our
3775 interests and expertise span a broad range of related fields, and one
3776 of our primary, long-term objectives is the development of a powerful
3777 information management
3778 system with open network interfaces and hypermedia capabilities.
3779
3780 We make this software available free of charge, on a fairly unrestrictive
3781 license; as a service to the networking community, and to further the
3782 development of quality software for open network communication.
3783
3784 We'll be happy to answer questions about the software, and about ourselves
3785 in general.
3786
3787 <tscreen><verb>
3788 Index Data Aps
3789 KĂžbmagergade 43
3790 DK-1150 Copenhagen K
3791 </verb></tscreen>
3792
3793 <p>
3794 <tscreen><verb>
3795 Phone: +45 3341 0100
3796 Fax  : +45 3341 0101
3797 Email: info@indexdata.dk
3798 </verb></tscreen>
3799
3800 The <it>Hacker's Jargon File</it> has the following to say about the
3801 use of the
3802 prefix &dquot;YA&dquot; in the name of a software product.
3803
3804 <it>
3805 Yet Another. adj. 1. Of your own work: A
3806 humorous allusion often used in titles to acknowledge that the
3807 topic is not original, though the content is.  As in &dquot;Yet Another
3808 AI Group&dquot; or &dquot;Yet Another Simulated Annealing Algorithm&dquot;.
3809 2. Of
3810 others' work: Describes something of which there are already far
3811 too many.
3812 </it>
3813
3814 </article>