2 * Copyright (C) 1994, Index Data I/S
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.7 1995-03-21 15:53:31 quinn
10 * Revision 1.6 1995/03/21 12:30:09 quinn
11 * Beginning to add support for record packing.
13 * Revision 1.5 1995/03/17 10:44:13 quinn
14 * Added catch of null-string in makediagrec
16 * Revision 1.4 1995/03/17 10:18:08 quinn
17 * Added memory management.
19 * Revision 1.3 1995/03/16 17:42:39 quinn
22 * Revision 1.2 1995/03/16 13:29:01 quinn
25 * Revision 1.1 1995/03/15 16:02:10 quinn
26 * Modded session.c seshigh.c
28 * Revision 1.10 1995/03/15 15:18:51 quinn
29 * Little changes to better support nonblocking I/O
32 * Revision 1.9 1995/03/15 13:20:23 adam
33 * Yet another bug fix in very dummy_database...
35 * Revision 1.8 1995/03/15 11:18:17 quinn
38 * Revision 1.7 1995/03/15 09:40:15 adam
39 * Bug fixes in dummy_database_...
41 * Revision 1.6 1995/03/15 09:08:30 adam
42 * Take care of preferredMessageSize.
44 * Revision 1.5 1995/03/15 08:37:44 quinn
45 * Now we're pretty much set for nonblocking I/O.
47 * Revision 1.4 1995/03/15 08:27:20 adam
48 * PresentRequest changed to return MARC records from file 'dummy-records'.
50 * Revision 1.3 1995/03/14 16:59:48 quinn
53 * Revision 1.2 1995/03/14 11:30:14 quinn
56 * Revision 1.1 1995/03/14 10:28:01 quinn
57 * More work on demo server.
74 #define ENCODE_BUFFER_SIZE 10000
76 static int process_apdu(IOCHAN chan);
77 static int process_initRequest(IOCHAN client, Z_InitRequest *req);
78 static int process_searchRequest(IOCHAN client, Z_SearchRequest *req);
79 static int process_presentRequest(IOCHAN client, Z_PresentRequest *req);
81 association *create_association(IOCHAN channel, COMSTACK link)
85 if (!(new = malloc(sizeof(*new))))
87 new->client_chan = channel;
88 new->client_link = link;
89 if (!(new->decode = odr_createmem(ODR_DECODE)) ||
90 !(new->encode = odr_createmem(ODR_ENCODE)))
92 if (!(new->encode_buffer = malloc(ENCODE_BUFFER_SIZE)))
94 odr_setbuf(new->encode, new->encode_buffer, ENCODE_BUFFER_SIZE);
95 new->state = ASSOC_UNINIT;
96 new->input_buffer = 0;
97 new->input_buffer_len = 0;
101 void destroy_association(association *h)
103 odr_destroy(h->decode);
104 odr_destroy(h->encode);
105 free(h->encode_buffer);
107 free(h->input_buffer);
111 void ir_session(IOCHAN h, int event)
114 association *assoc = iochan_getdata(h);
115 COMSTACK conn = assoc->client_link;
117 if (event == EVENT_INPUT)
119 assert(assoc && conn);
120 res = cs_get(conn, &assoc->input_buffer, &assoc->input_buffer_len);
123 case 0: case -1: /* connection closed by peer */
124 fprintf(stderr, "Closed connection\n");
126 destroy_association(assoc);
129 case 1: /* incomplete read */
132 assoc->input_apdu_len = res;
133 if (process_apdu(h) < 0)
135 fprintf(stderr, "Operation failed\n");
137 destroy_association(assoc);
140 else if (cs_more(conn)) /* arrange to be called again */
141 iochan_setevent(h, EVENT_INPUT);
144 else if (event == EVENT_OUTPUT)
146 switch (res = cs_put(conn, assoc->encode_buffer, assoc->encoded_len))
149 fprintf(stderr, "Closed connection\n");
151 destroy_association(assoc);
153 case 0: /* all sent */
154 iochan_setflags(h, EVENT_INPUT | EVENT_EXCEPT); /* reset */
156 case 1: /* partial send */
157 break; /* we'll get called again */
160 else if (event == EVENT_EXCEPT)
162 fprintf(stderr, "Exception on line\n");
164 destroy_association(assoc);
169 static int process_apdu(IOCHAN chan)
173 association *assoc = iochan_getdata(chan);
175 odr_setbuf(assoc->decode, assoc->input_buffer, assoc->input_apdu_len);
176 if (!z_APDU(assoc->decode, &apdu, 0))
178 odr_perror(assoc->decode, "Incoming APDU");
183 case Z_APDU_initRequest:
184 res = process_initRequest(chan, apdu->u.initRequest); break;
185 case Z_APDU_searchRequest:
186 res = process_searchRequest(chan, apdu->u.searchRequest); break;
187 case Z_APDU_presentRequest:
188 res = process_presentRequest(chan, apdu->u.presentRequest); break;
190 fprintf(stderr, "Bad APDU\n");
193 odr_reset(assoc->decode);
197 static int process_initRequest(IOCHAN client, Z_InitRequest *req)
202 association *assoc = iochan_getdata(client);
203 bend_initrequest binitreq;
204 bend_initresult *binitres;
206 fprintf(stderr, "Got initRequest.\n");
207 if (req->implementationId)
208 fprintf(stderr, "Id: %s\n", req->implementationId);
209 if (req->implementationName)
210 fprintf(stderr, "Name: %s\n", req->implementationName);
211 if (req->implementationVersion)
212 fprintf(stderr, "Version: %s\n", req->implementationVersion);
214 binitreq.configname = "default-config";
215 if (!(binitres = bend_init(&binitreq)) || binitres->errcode)
217 fprintf(stderr, "Bad response from backend\n");
222 apdu.which = Z_APDU_initResponse;
223 apdu.u.initResponse = &resp;
224 resp.referenceId = req->referenceId;
225 resp.options = req->options; /* should check these */
226 resp.protocolVersion = req->protocolVersion;
227 assoc->maximumRecordSize = *req->maximumRecordSize;
228 if (assoc->maximumRecordSize > ENCODE_BUFFER_SIZE - 500)
229 assoc->maximumRecordSize = ENCODE_BUFFER_SIZE - 500;
230 assoc->preferredMessageSize = *req->preferredMessageSize;
231 if (assoc->preferredMessageSize > assoc->maximumRecordSize)
232 assoc->preferredMessageSize = assoc->maximumRecordSize;
233 resp.preferredMessageSize = &assoc->preferredMessageSize;
234 resp.maximumRecordSize = &assoc->maximumRecordSize;
235 resp.result = &result;
236 resp.implementationId = "YAZ";
237 resp.implementationName = "YAZ/Simple asynchronous test server";
238 resp.implementationVersion = "$Revision: 1.7 $";
239 resp.userInformationField = 0;
240 if (!z_APDU(assoc->encode, &apdup, 0))
242 odr_perror(assoc->encode, "Encode initres");
245 odr_getbuf(assoc->encode, &assoc->encoded_len);
246 odr_reset(assoc->encode);
247 iochan_setflags(client, EVENT_OUTPUT | EVENT_EXCEPT);
251 static Z_Records *diagrec(int error, char *addinfo)
253 static Z_Records rec;
254 static Odr_oid bib1[] = { 1, 2, 3, 4, 5, -1 };
258 fprintf(stderr, "Diagnostic: %d -- %s\n", error, addinfo ? addinfo :
261 rec.which = Z_Records_NSD;
262 rec.u.nonSurrogateDiagnostic = &dr;
263 dr.diagnosticSetId = bib1;
265 dr.addinfo = addinfo ? addinfo : "";
269 static Z_NamePlusRecord *surrogatediagrec(char *dbname, int error,
272 static Z_NamePlusRecord rec;
274 static Odr_oid bib1[] = { 1, 2, 3, 4, 5, -1 };
277 fprintf(stderr, "SurrogateDiagnotic: %d -- %s\n", error, addinfo);
278 rec.databaseName = dbname;
279 rec.which = Z_NamePlusRecord_surrogateDiagnostic;
280 rec.u.surrogateDiagnostic = &dr;
281 dr.diagnosticSetId = bib1;
283 dr.addinfo = addinfo ? addinfo : "";
287 static Z_Records *pack_records(association *a, int num, Z_ElementSetNames *esn)
291 static int process_searchRequest(IOCHAN client, Z_SearchRequest *req)
294 Z_SearchResponse resp;
295 association *assoc = iochan_getdata(client);
299 bend_searchrequest bsrq;
300 bend_searchresult *bsrt;
302 fprintf(stderr, "Got SearchRequest.\n");
304 apdu.which = Z_APDU_searchResponse;
305 apdu.u.searchResponse = &resp;
306 resp.referenceId = req->referenceId;
308 bsrq.setname = req->resultSetName;
309 bsrq.replace_set = *req->replaceIndicator;
310 bsrq.num_bases = req->num_databaseNames;
311 bsrq.basenames = req->databaseNames;
312 bsrq.query = req->query;
314 if (!(bsrt = bend_search(&bsrq)))
316 else if (bsrt->errcode)
317 resp.records = diagrec(bsrt->errcode, bsrt->errstring);
321 resp.resultCount = &bsrt->hits;
322 resp.numberOfRecordsReturned = &nulint;
323 nrp = bsrt->hits ? 1 : 0;
324 resp.nextResultSetPosition = &nrp;
325 resp.searchStatus = &sr;
326 resp.resultSetStatus = &sr;
327 resp.presentStatus = 0;
329 if (!z_APDU(assoc->encode, &apdup, 0))
331 odr_perror(assoc->encode, "Encode searchres");
334 odr_getbuf(assoc->encode, &assoc->encoded_len);
335 odr_reset(assoc->encode);
336 iochan_setflags(client, EVENT_OUTPUT | EVENT_EXCEPT);
340 static int process_presentRequest(IOCHAN client, Z_PresentRequest *req)
343 Z_PresentResponse resp;
344 association *assoc = iochan_getdata(client);
347 fprintf(stderr, "Got PresentRequest.\n");
349 apdu.which = Z_APDU_presentResponse;
350 apdu.u.presentResponse = &resp;
351 resp.referenceId = req->referenceId;
353 resp.numberOfRecordsReturned = &nrr;
354 resp.nextResultSetPosition = &nrr;
355 resp.presentStatus = &nrr;
357 resp.records = diagrec(1, "No records yet.");
359 if (!z_APDU(assoc->encode, &apdup, 0))
361 odr_perror(assoc->encode, "Encode presentres");
364 odr_getbuf(assoc->encode, &assoc->encoded_len);
365 odr_reset(assoc->encode);
366 iochan_setflags(client, EVENT_OUTPUT | EVENT_EXCEPT);