.../zprise_1/zserver/src/bin/zserver
Main function knows nothing about Z39.50 or any IR application.
It invokes zserver functions:
- init_zserver(): reads table of databases
and set default pdus;
- zserver(): loops on incoming msgs from
the client (via socket) until terminate
- close_zserver(): release resources
main.c
.../zprise_1/zserver/src/lib/zserver
IR application-independent server code which:
- initializes database table and defaults
- loops
reads incoming msg in BER-format from socket
translates incoming msg to incoming PDU
invokes zservices level (process_PDU())
translates outgoing PDU to BER-format msg
writes outgoing msg to socket
- releases resources when server closes down
zserver.c
.../zprise_1/zserver/src/lib/zservices
IR application-independent code to process
PDUs and invoke the application-specific
functions (e.g. those in /zprise) that
in turn invoke the IR application functions
proper.
Based on the PDU choice id, process_PDU()
invokes the routines (init, process, close)
defined for the operation in op_table.c
databases.c
default_pdus.c
zservices.c #includes:
access.c
close.c
delete.c
extended.c
init.c implemented
present.c implemented
search.c implemented
scan.c
segment.c
sort.c
resource.c
op_table.c Table of pointers to
Z3950 operation functions
(e.g., init_search,
search,...) indexed by
PDU id.
.../zprise_1/zserver/src/lib/zprise
This layer bridges any gap between the layer (zservices) above it, which
knows about the Z39.50 protocol, and the particular IR application layer
below it (e.g. PRISE). This is the layer that may require adjustment when
a new IR application is inserted.
ap_services.c #includes:
ap_initdb.c implemented for PRISE
ap_search.c implemented for PRISE
ap_present.c implemented for PRISE
ap_closedb.c
-----------
Extensions to ap_help.c implemented for PRISE
Z39.50 search ap_generic.c
ap_feedback.c
.../zprise_1/prise-search
This is the IR application proper.
See"Adding/substituting your own search engine" for more detailed information on how the zserver interfaces to an IR application.
main()
-> init_zserver()
-> zserver() Loop awaiting/processing incoming msgs
--> process_msg() Handle single message from socket
---> ber2pdu() Translate BER-encoded msg into PDU
---> process_PDU() Take a request PDU; return a response PDU
----> ap_table_entry.init == Initialization
by operation
> init_search() (no init_init())
> init_present()
----> ap_table_entry.proc == Main processing
by operation
> init()
-----> get_db_list()
-----> init_default_pdus(
> search()
-----> MakeSearchResponse()
-----> ap_link() Find ap_service_-
entry for IR app.
given db. name
-----> ap_service_entry.delete == Release result
> ap_delete() set resources
-----> ap_service_entry.init_search == Get ready to
> init_ap_search() search
-----> ap_service_entry.search == Perform search
> ap_search()
-----> get_elementSetType() Get some format
info
loop-> ap_service_entry.present == Get a database
> ap_present() record and turn
it into a
retrieval recd.
> InsertResponseRecord() Add retrieval
record or sur-
rogate to the
response
-----> ap_service_entry.close_search ==
> close_ap_search()
> present()
-----> MakePresentResponse()
-----> ap_service_entry.init_present ==
> init_ap_present()
-----> get_elementSetType()
loop-> ap_service_entry.present == See above
> ap_present()
> InsertResponseRecord() See above
-----> ap_service_entry.close_present ==
> close_ap_present()
----> ap_table_entry.close == Close processing
by operation
> close_search()
> close_present()
---> pdu2ber() Translate out-
PDU to BER-
encoded msg.
---> FreePDU()
---> FreePDU()
-> close_zserver()
--> free_dbs()
In general the Zserver has been written to be tolerant of invalid requests. So, for example, the zserver looks for an element set name of F or B but finding G instead or none, it uses its default. If the result set contains 3 records and the client asks for 4 starting with the third, the zserver just returns as many as it can (1).
The zserver always attempts to write a message to the log file
/tmp/zserver.RELEVANT-PID.log
when it encounters a processing error. It attempts to communicate the situation
to the client via the PDU and stay up. However, in the following circumstances
the zserver will log a message and exit:
- Errors encountered before the msg-read/write loop in process_msg() is entered
- Errors encountered down in the PRISE search engine
- Memory allocation errors
Note that socket processing takes over standard in, out, and error, so writing to standard error will bring the zserver down.