*** empty log message ***
[yaz-moved-to-github.git] / asn / proto.c
1 /*
2  * Copyright (c) 1995, Index Data
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: proto.c,v $
7  * Revision 1.25  1995-05-25 11:00:08  quinn
8  * *** empty log message ***
9  *
10  * Revision 1.24  1995/05/22  13:58:18  quinn
11  * Fixed an ODR_NULLVAL.
12  *
13  * Revision 1.23  1995/05/22  11:30:18  quinn
14  * Adding Z39.50-1992 stuff to proto.c. Adding zget.c
15  *
16  * Revision 1.22  1995/05/17  08:40:56  quinn
17  * Added delete. Fixed some sequence_begins. Smallish.
18  *
19  * Revision 1.21  1995/05/16  08:50:24  quinn
20  * License, documentation, and memory fixes
21  *
22  * Revision 1.20  1995/05/15  11:55:25  quinn
23  * Smallish.
24  *
25  * Revision 1.19  1995/04/11  11:58:35  quinn
26  * Fixed bug.
27  *
28  * Revision 1.18  1995/04/11  11:52:02  quinn
29  * Fixed possible buf in proto.c
30  *
31  * Revision 1.17  1995/04/10  10:22:22  quinn
32  * Added SCAN.
33  *
34  * Revision 1.16  1995/03/30  10:26:43  quinn
35  * Added Term structure
36  *
37  * Revision 1.15  1995/03/30  09:08:39  quinn
38  * Added Resource control protocol
39  *
40  * Revision 1.14  1995/03/29  08:06:13  quinn
41  * Added a few v3 elements
42  *
43  * Revision 1.13  1995/03/20  11:26:52  quinn
44  * *** empty log message ***
45  *
46  * Revision 1.12  1995/03/20  09:45:09  quinn
47  * Working towards v3
48  *
49  * Revision 1.11  1995/03/17  10:17:25  quinn
50  * Added memory management.
51  *
52  * Revision 1.10  1995/03/15  11:17:40  quinn
53  * Fixed some return-checks from choice.. need better ay to handle those..
54  *
55  * Revision 1.9  1995/03/15  08:37:06  quinn
56  * Fixed protocol bugs.
57  *
58  * Revision 1.8  1995/03/14  16:59:24  quinn
59  * Fixed OPTIONAL flag in attributeelement
60  *
61  * Revision 1.7  1995/03/07  16:29:33  quinn
62  * Added authentication stuff.
63  *
64  * Revision 1.6  1995/03/01  14:46:03  quinn
65  * Fixed protocol bug in 8777query.
66  *
67  * Revision 1.5  1995/02/14  11:54:22  quinn
68  * Fixing include.
69  *
70  * Revision 1.4  1995/02/10  15:54:30  quinn
71  * Small adjustments.
72  *
73  * Revision 1.3  1995/02/09  15:51:39  quinn
74  * Works better now.
75  *
76  * Revision 1.2  1995/02/06  21:26:07  quinn
77  * Repaired this evening's damages..
78  *
79  * Revision 1.1  1995/02/06  16:44:47  quinn
80  * First hack at Z/SR protocol
81  *
82  */
83
84 #include <odr.h>
85
86 #include <proto.h>
87
88 /* ---------------------- GLOBAL DEFS ------------------- */
89
90 int z_ReferenceId(ODR o, Z_ReferenceId **p, int opt)
91 {
92     return odr_implicit(o, odr_octetstring, (Odr_oct**) p, ODR_CONTEXT, 2, opt);
93 }
94
95 int z_DatabaseName(ODR o, Z_DatabaseName **p, int opt)
96 {
97     return odr_implicit(o, odr_visiblestring, (char **) p, ODR_CONTEXT, 105,
98         opt);
99 }
100
101 int z_ResultSetId(ODR o, char **p, int opt)
102 {
103     return odr_implicit(o, odr_visiblestring, (char **) p, ODR_CONTEXT, 31,
104         opt);
105 }
106
107 int z_UserInformationField(ODR o, Z_UserInformationField **p, int opt)
108 {
109     return odr_explicit(o, odr_external, (Odr_external **)p, ODR_CONTEXT,
110         11, opt);
111 }
112
113 /* ---------------------- INITIALIZE SERVICE ------------------- */
114
115 #if 0
116 int z_NSRAuthentication(ODR o, Z_NSRAuthentication **p, int opt)
117 {
118     if (!odr_sequence_begin(o, p, sizeof(**p)))
119         return opt && odr_ok(o);
120     return
121         odr_visiblestring(o, &(*p)->user, 0) &&
122         odr_visiblestring(o, &(*p)->password, 0) &&
123         odr_visiblestring(o, &(*p)->account, 0) &&
124         odr_sequence_end(o);
125 }
126 #endif
127
128 int z_IdPass(ODR o, Z_IdPass **p, int opt)
129 {
130     if (!odr_sequence_begin(o, p, sizeof(**p)))
131         return opt && odr_ok(o);
132     return
133         odr_implicit(o, odr_visiblestring, &(*p)->groupId, ODR_CONTEXT, 0, 1) &&
134         odr_implicit(o, odr_visiblestring, &(*p)->userId, ODR_CONTEXT, 1, 1) &&
135         odr_implicit(o, odr_visiblestring, &(*p)->password, ODR_CONTEXT, 2,
136             1) &&
137         odr_sequence_end(o);
138 }
139
140 int z_StrAuthentication(ODR o, char **p, int opt)
141 {
142     return odr_visiblestring(o, p, opt);
143 }
144
145 int z_IdAuthentication(ODR o, Z_IdAuthentication **p, int opt)
146 {
147     static Odr_arm arm[] =
148     {
149         {-1, -1, -1, Z_IdAuthentication_open, z_StrAuthentication},
150         {-1, -1, -1, Z_IdAuthentication_idPass, z_IdPass},
151         {-1, -1, -1, Z_IdAuthentication_anonymous, odr_null},
152         {-1, -1, -1, Z_IdAuthentication_other, odr_external},
153         {-1, -1, -1, -1, 0}
154     };
155
156     if (o->direction == ODR_DECODE)
157         *p = odr_malloc(o, sizeof(**p));
158
159     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
160         return 1;
161     *p = 0;
162     return opt && odr_ok(o);
163 }
164
165 int z_InitRequest(ODR o, Z_InitRequest **p, int opt)
166 {
167     Z_InitRequest *pp;
168
169     if (!odr_sequence_begin(o, p, sizeof(**p)))
170         return opt && odr_ok(o);
171     pp = *p;
172     return
173         z_ReferenceId(o, &pp->referenceId, 1) &&
174         odr_implicit(o, odr_bitstring, &pp->protocolVersion, ODR_CONTEXT, 
175             3, 0) &&
176         odr_implicit(o, odr_bitstring, &pp->options, ODR_CONTEXT, 4, 0) &&
177         odr_implicit(o, odr_integer, &pp->preferredMessageSize, ODR_CONTEXT,
178             5, 0) &&
179         odr_implicit(o, odr_integer, &pp->maximumRecordSize, ODR_CONTEXT,
180             6, 0) &&
181         odr_explicit(o, z_IdAuthentication, &pp->idAuthentication, ODR_CONTEXT,
182             7, 1) &&
183         odr_implicit(o, odr_visiblestring, &pp->implementationId, ODR_CONTEXT,
184             110, 1) &&
185         odr_implicit(o, odr_visiblestring, &pp->implementationName, ODR_CONTEXT,
186             111, 1) &&
187         odr_implicit(o, odr_visiblestring, &pp->implementationVersion,
188             ODR_CONTEXT, 112, 1) &&
189         z_UserInformationField(o, &pp->userInformationField, 1) &&
190 #ifdef Z_OTHERINFO
191         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
192 #endif
193         odr_sequence_end(o);
194 }
195
196 int z_InitResponse(ODR o, Z_InitResponse **p, int opt)
197 {
198     Z_InitResponse *pp;
199
200     if (!odr_sequence_begin(o, p, sizeof(**p)))
201         return opt && odr_ok(o);
202     pp = *p;
203     return
204         z_ReferenceId(o, &pp->referenceId, 1) &&
205         odr_implicit(o, odr_bitstring, &pp->protocolVersion, ODR_CONTEXT, 
206             3, 0) &&
207         odr_implicit(o, odr_bitstring, &pp->options, ODR_CONTEXT, 4, 0) &&
208         odr_implicit(o, odr_integer, &pp->preferredMessageSize, ODR_CONTEXT,
209             5, 0) &&
210         odr_implicit(o, odr_integer, &pp->maximumRecordSize, ODR_CONTEXT,
211             6, 0) &&
212         odr_implicit(o, odr_bool, &pp->result, ODR_CONTEXT, 12, 0) &&
213         odr_implicit(o, odr_visiblestring, &pp->implementationId, ODR_CONTEXT,
214             110, 1) &&
215         odr_implicit(o, odr_visiblestring, &pp->implementationName, ODR_CONTEXT,
216             111, 1) &&
217         odr_implicit(o, odr_visiblestring, &pp->implementationVersion,
218             ODR_CONTEXT, 112, 1) &&
219         z_UserInformationField(o, &pp->userInformationField, 1) &&
220 #ifdef Z_OTHERINFO
221         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
222 #endif
223         odr_sequence_end(o);
224 }
225
226 /* ------------------ RESOURCE CONTROL ----------------*/
227
228 int z_TriggerResourceControlRequest(ODR o, Z_TriggerResourceControlRequest **p,
229                                     int opt)
230 {
231     if (!odr_sequence_begin(o, p, sizeof(**p)))
232         return opt && odr_ok(o);
233     return
234         z_ReferenceId(o, &(*p)->referenceId, 1) &&
235         odr_implicit(o, odr_integer, &(*p)->requestedAction, ODR_CONTEXT,
236             46, 0) &&
237         odr_implicit(o, odr_oid, &(*p)->prefResourceReportFormat,
238             ODR_CONTEXT, 47, 1) &&
239         odr_implicit(o, odr_bool, &(*p)->resultSetWanted, ODR_CONTEXT,
240             48, 1) &&
241 #ifdef Z_OTHERINFO
242         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
243 #endif
244         odr_sequence_end(o);
245 }
246
247 int z_ResourceControlRequest(ODR o, Z_ResourceControlRequest **p, int opt)
248 {
249     if (!odr_sequence_begin(o, p, sizeof(**p)))
250         return opt && odr_ok(o);
251     return
252         z_ReferenceId(o, &(*p)->referenceId, 1) &&
253         odr_implicit(o, odr_bool, &(*p)->suspendedFlag, ODR_CONTEXT, 39, 1)&&
254         odr_explicit(o, odr_external, &(*p)->resourceReport, ODR_CONTEXT,
255             40, 1) &&
256         odr_implicit(o, odr_integer, &(*p)->partialResultsAvailable,
257             ODR_CONTEXT, 41, 1) &&
258         odr_implicit(o, odr_bool, &(*p)->responseRequired, ODR_CONTEXT,
259             42, 0) &&
260         odr_implicit(o, odr_bool, &(*p)->triggeredRequestFlag,
261             ODR_CONTEXT, 43, 1) &&
262 #ifdef Z_OTHERINFO
263         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
264 #endif
265         odr_sequence_end(o);
266 }
267
268 int z_ResourceControlResponse(ODR o, Z_ResourceControlResponse **p, int opt)
269 {
270     if (!odr_sequence_begin(o, p, sizeof(**p)))
271         return opt && odr_ok(o);
272     return
273         z_ReferenceId(o, &(*p)->referenceId, 1) &&
274         odr_implicit(o, odr_bool, &(*p)->continueFlag, ODR_CONTEXT, 44, 0) &&
275         odr_implicit(o, odr_bool, &(*p)->resultSetWanted, ODR_CONTEXT,
276             45, 1) &&
277 #ifdef Z_OTHERINFO
278         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
279 #endif
280         odr_sequence_end(o);
281 }
282
283 /* ------------------------ SEARCH SERVICE ----------------------- */
284
285 int z_ElementSetName(ODR o, char **p, int opt)
286 {
287     return odr_implicit(o, odr_visiblestring, (char**) p, ODR_CONTEXT, 103,
288         opt);
289 }
290
291 int z_PreferredRecordSyntax(ODR o, Z_PreferredRecordSyntax **p, int opt)
292 {
293     return odr_implicit(o, odr_oid, (Odr_oid**) p, ODR_CONTEXT, 104, opt);
294 }
295
296 int z_DatabaseSpecificUnit(ODR o, Z_DatabaseSpecificUnit **p, int opt)
297 {
298     if (!odr_sequence_begin(o, p, sizeof(**p)))
299         return opt && odr_ok(o);
300     return
301         z_DatabaseName(o, &(*p)->databaseName, 0) &&
302         z_ElementSetName(o, &(*p)->elementSetName, 0) &&
303         odr_sequence_end(o);
304 }
305
306 int z_DatabaseSpecific(ODR o, Z_DatabaseSpecific **p, int opt)
307 {
308     if (o->direction == ODR_DECODE)
309         *p = odr_malloc(o, sizeof(**p));
310     else if (!*p)
311         return opt;
312
313     odr_implicit_settag(o, ODR_CONTEXT, 1);
314     if (odr_sequence_of(o, z_DatabaseSpecificUnit, &(*p)->elements,
315         &(*p)->num_elements))
316         return 1;
317     *p = 0;
318     return 0;
319 }
320
321 int z_ElementSetNames(ODR o, Z_ElementSetNames **p, int opt)
322 {
323     static Odr_arm arm[] =
324     {
325         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_ElementSetNames_generic,
326             z_ElementSetName},
327         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ElementSetNames_databaseSpecific,
328             z_DatabaseSpecific},
329         {-1, -1, -1, -1, 0}
330     };
331
332     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 19))
333         return opt && odr_ok(o);
334
335     if (o->direction == ODR_DECODE)
336         *p = odr_malloc(o, sizeof(**p));
337
338     if (odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
339         odr_constructed_end(o))
340         return 1;
341     *p = 0;
342     return 0;
343 }
344
345 /* ----------------------- RPN QUERY -----------------------*/
346
347 int z_AttributeElement(ODR o, Z_AttributeElement **p, int opt)
348 {
349     if (!odr_sequence_begin(o, p, sizeof(**p)))
350         return opt && odr_ok(o);
351     return
352         odr_implicit(o, odr_integer, &(*p)->attributeType, ODR_CONTEXT,
353             120, 0) &&
354         odr_implicit(o, odr_integer, &(*p)->attributeValue, ODR_CONTEXT,
355             121, 0) &&
356         odr_sequence_end(o);
357 }
358
359 #ifdef Z_V3
360
361 int z_Term(ODR o, Z_Term **p, int opt)
362 {
363     static Odr_arm arm[] =
364     {
365         {ODR_IMPLICIT, ODR_CONTEXT, 45, Z_Term_general, odr_octetstring},
366         {ODR_IMPLICIT, ODR_CONTEXT, 215, Z_Term_numeric, odr_integer},
367         {ODR_IMPLICIT, ODR_CONTEXT, 216, Z_Term_characterString,
368             odr_visiblestring},
369         {ODR_IMPLICIT, ODR_CONTEXT, 217, Z_Term_oid, odr_oid},
370         {ODR_IMPLICIT, ODR_CONTEXT, 218, Z_Term_dateTime, odr_cstring},
371         {ODR_IMPLICIT, ODR_CONTEXT, 219, Z_Term_external, odr_external},
372         /* add intUnit here */
373         {ODR_IMPLICIT, ODR_CONTEXT, 221, Z_Term_null, odr_null},
374         {-1, -1, -1, -1, 0}
375     };
376
377     if (o->direction ==ODR_DECODE)
378         *p = odr_malloc(o, sizeof(**p));
379     else if (!*p)
380         return opt;
381     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
382         return 1;
383     *p = 0;
384     return opt && odr_ok(o);
385 }
386
387 #endif
388
389 int z_AttributesPlusTerm(ODR o, Z_AttributesPlusTerm **p, int opt)
390 {
391     if (!(odr_implicit_settag(o, ODR_CONTEXT, 102) &&
392         odr_sequence_begin(o, p, sizeof(**p))))
393         return opt && odr_ok(o);
394     return
395         odr_implicit_settag(o, ODR_CONTEXT, 44) &&
396         odr_sequence_of(o, z_AttributeElement, &(*p)->attributeList,
397             &(*p)->num_attributes) &&
398         z_Term(o, &(*p)->term, 0) &&
399         odr_sequence_end(o);
400 }
401
402 int z_ProximityOperator(ODR o, Z_ProximityOperator **p, int opt)
403 {
404     static Odr_arm arm[] =
405     {
406         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ProxCode_known, odr_integer},
407         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ProxCode_private, odr_integer},
408         {-1, -1, -1, -1, 0}
409     };
410
411     if (!odr_sequence_begin(o, p, sizeof(**p)))
412         return opt && odr_ok(o);
413     return
414         odr_implicit(o, odr_bool, &(*p)->exclusion, ODR_CONTEXT, 1, 1) &&
415         odr_implicit(o, odr_integer, &(*p)->distance, ODR_CONTEXT, 2, 0) &&
416         odr_implicit(o, odr_bool, &(*p)->ordered, ODR_CONTEXT, 3, 0) &&
417         odr_implicit(o, odr_integer, &(*p)->relationType, ODR_CONTEXT, 4, 0) &&
418         odr_constructed_begin(o, &(*p)->proximityUnitCode, ODR_CONTEXT, 5) &&
419         odr_choice(o, arm, &(*p)->proximityUnitCode, &(*p)->which) &&
420         odr_constructed_end(o) &&
421         odr_sequence_end(o);
422 }
423
424 int z_Operator(ODR o, Z_Operator **p, int opt)
425 {
426     static Odr_arm arm[] =
427     {
428         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_Operator_and, odr_null},
429         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Operator_or, odr_null},
430         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_Operator_and_not, odr_null},
431         {ODR_IMPLICIT, ODR_CONTEXT, 3, Z_Operator_prox, z_ProximityOperator},
432         {-1, -1, -1, -1, 0}
433     };
434
435     if (!*p && o->direction != ODR_DECODE)
436         return opt;
437     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 46))
438         return opt && odr_ok(o);
439     if (o->direction == ODR_DECODE)
440         *p = odr_malloc(o, sizeof(**p));
441     else
442         (*p)->u.and = ODR_NULLVAL;
443
444     if (odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
445         odr_constructed_end(o))
446         return 1;
447     *p = 0;
448     return opt && odr_ok(o);
449 }
450
451 int z_Operand(ODR o, Z_Operand **p, int opt)
452 {
453     static Odr_arm arm[] =
454     {
455         {-1, -1, -1, Z_Operand_APT, z_AttributesPlusTerm},
456         {-1, -1, -1, Z_Operand_resultSetId, z_ResultSetId},
457         {-1, -1, -1, -1, 0}
458     };
459
460     if (o->direction ==ODR_DECODE)
461         *p = odr_malloc(o, sizeof(**p));
462     else if (!*p)
463         return opt;
464     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
465         return 1;
466     *p = 0;
467     return opt && odr_ok(o);
468 }
469
470 int z_RPNStructure(ODR o, Z_RPNStructure **p, int opt);
471
472 int z_Complex(ODR o, Z_Complex **p, int opt)
473 {
474     if (!odr_sequence_begin(o, p, sizeof(**p)))
475         return opt && odr_ok(o);
476     return
477         z_RPNStructure(o, &(*p)->s1, 0) &&
478         z_RPNStructure(o, &(*p)->s2, 0) &&
479         z_Operator(o, &(*p)->operator, 0) &&
480         odr_sequence_end(o);
481 }
482
483 int z_RPNStructure(ODR o, Z_RPNStructure **p, int opt)
484 {
485     static Odr_arm arm[] = 
486     {
487         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_RPNStructure_simple, z_Operand},
488         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_RPNStructure_complex, z_Complex},
489         {-1 -1, -1, -1, 0}
490     };
491
492     if (o->direction == ODR_DECODE)
493         *p = odr_malloc(o, sizeof(**p));
494     else if (!*p)
495         return opt;
496     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
497         return 1;
498     *p = 0;
499     return opt && odr_ok(o);
500 }
501
502 int z_RPNQuery(ODR o, Z_RPNQuery **p, int opt)
503 {
504     if (!odr_sequence_begin(o, p, sizeof(**p)))
505         return opt && odr_ok(o);
506     return
507         odr_oid(o, &(*p)->attributeSetId, 0) &&
508         z_RPNStructure(o, &(*p)->RPNStructure, 0) &&
509         odr_sequence_end(o);
510 }
511
512 /* -----------------------END RPN QUERY ----------------------- */
513
514 int z_Query(ODR o, Z_Query **p, int opt)
515 {
516     static Odr_arm arm[] = 
517     {
518         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Query_type_1, z_RPNQuery},
519         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_Query_type_2, odr_octetstring},
520         {-1, -1, -1, -1, 0}
521     };
522
523     if (o->direction == ODR_DECODE)
524         *p = odr_malloc(o, sizeof(**p));
525     else if (!*p)
526         return opt;
527     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
528         return 1;
529     *p = 0;
530     return opt && odr_ok(o);
531 }
532
533 int z_SearchRequest(ODR o, Z_SearchRequest **p, int opt)
534 {
535     Z_SearchRequest *pp;
536
537     if (!odr_sequence_begin(o, p, sizeof(**p)))
538         return opt && odr_ok(o);
539     pp = *p;
540     return
541         z_ReferenceId(o, &pp->referenceId, 1) &&
542         odr_implicit(o, odr_integer, &pp->smallSetUpperBound, ODR_CONTEXT,
543             13, 0) &&
544         odr_implicit(o, odr_integer, &pp->largeSetLowerBound, ODR_CONTEXT,
545             14, 0) &&
546         odr_implicit(o, odr_integer, &pp->mediumSetPresentNumber, ODR_CONTEXT,
547             15, 0) &&
548         odr_implicit(o, odr_bool, &pp->replaceIndicator, ODR_CONTEXT, 16, 1) &&
549         odr_implicit(o, odr_visiblestring, &pp->resultSetName, ODR_CONTEXT,
550             17, 9) &&
551         odr_implicit_settag(o, ODR_CONTEXT, 18) &&
552         odr_sequence_of(o, z_DatabaseName, &pp->databaseNames,
553             &pp->num_databaseNames) &&
554         odr_explicit(o, z_ElementSetNames, &pp->smallSetElementSetNames,
555             ODR_CONTEXT, 100, 1) &&
556         odr_explicit(o, z_ElementSetNames, &pp->mediumSetElementSetNames,
557             ODR_CONTEXT, 101, 1) &&
558         odr_implicit(o, z_PreferredRecordSyntax, &pp->preferredRecordSyntax,
559             ODR_CONTEXT, 104, 1) &&
560         odr_explicit(o, z_Query, &pp->query, ODR_CONTEXT, 21, 0) &&
561 #ifdef Z_OTHERINFO
562         odr_implicit(o, z_OtherInformation, &(*p)->additionalSearchInfo,
563             ODR_CONTEXT, 203, 1) &&
564         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
565 #endif
566         odr_sequence_end(o);
567 }
568
569 /* ------------------------ RECORD ------------------------- */
570
571 int z_DatabaseRecord(ODR o, Z_DatabaseRecord **p, int opt)
572 {
573     return odr_external(o, (Odr_external **) p, opt);
574 }
575
576 int z_DiagRec(ODR o, Z_DiagRec **p, int opt)
577 {
578     if (!odr_sequence_begin(o, p, sizeof(**p)))
579         return opt && odr_ok(o);
580     return
581         odr_oid(o, &(*p)->diagnosticSetId, 1) &&       /* SHOULD NOT BE OPT */
582         odr_integer(o, &(*p)->condition, 0) &&
583         (odr_visiblestring(o, &(*p)->addinfo, 0) ||
584         odr_implicit(o, odr_cstring, &(*p)->addinfo, ODR_CONTEXT, ODR_VISIBLESTRING, 1)) &&
585         odr_sequence_end(o);
586 }
587
588 int z_NamePlusRecord(ODR o, Z_NamePlusRecord **p, int opt)
589 {
590     static Odr_arm arm[] =
591     {
592         {ODR_EXPLICIT, ODR_CONTEXT, 1, Z_NamePlusRecord_databaseRecord,
593             z_DatabaseRecord},
594         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_NamePlusRecord_surrogateDiagnostic,
595             z_DiagRec},
596         {-1, -1, -1, -1, 0}
597     };
598
599     if (!odr_sequence_begin(o, p, sizeof(**p)))
600         return opt && odr_ok(o);
601     return
602         odr_implicit(o, z_DatabaseName, &(*p)->databaseName, ODR_CONTEXT,
603             0, 1) &&
604         odr_constructed_begin(o, &(*p)->u, ODR_CONTEXT, 1) &&
605         odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
606         odr_constructed_end(o) &&
607         odr_sequence_end(o);
608 }
609
610 int z_NamePlusRecordList(ODR o, Z_NamePlusRecordList **p, int opt)
611 {
612     if (o->direction == ODR_DECODE)
613         *p = odr_malloc(o, sizeof(**p));
614     if (odr_sequence_of(o, z_NamePlusRecord, &(*p)->records,
615         &(*p)->num_records))
616         return 1;
617     *p = 0;
618     return 0;
619 }
620
621 int z_Records(ODR o, Z_Records **p, int opt)
622 {
623     Odr_arm arm[] = 
624     {
625         {ODR_IMPLICIT, ODR_CONTEXT, 28, Z_Records_DBOSD, z_NamePlusRecordList},
626         {ODR_IMPLICIT, ODR_CONTEXT, 130, Z_Records_NSD, z_DiagRec},
627         {-1, -1, -1, -1, 0}
628     };
629
630     if (o->direction == ODR_DECODE)
631         *p = odr_malloc(o, sizeof(**p));
632     else if (!*p)
633         return opt;
634     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
635         return 1;
636     *p = 0;
637     return opt && odr_ok(o);
638 }
639
640 /* ------------------------ ACCESS CTRL SERVICE ----------------------- */
641
642 int z_AccessControlRequest(ODR o, Z_AccessControlRequest **p, int opt)
643 {
644     static Odr_arm arm[] = 
645     {
646         {ODR_IMPLICIT, ODR_CONTEXT, 37, Z_AccessRequest_simpleForm,
647             odr_octetstring},
648         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_AccessRequest_externallyDefined,
649             odr_external},
650         {-1, -1, -1, -1, 0}
651     };
652     if (!odr_sequence_begin(o, p, sizeof(**p)))
653         return opt && odr_ok(o);
654     return
655         z_ReferenceId(o, &(*p)->referenceId, 1) &&
656         odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
657 #ifdef Z_OTHERINFO
658         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
659 #endif
660         odr_sequence_end(o);
661 }
662
663 int z_AccessControlResponse(ODR o, Z_AccessControlResponse **p, int opt)
664 {
665     static Odr_arm arm[] = 
666     {
667         {ODR_IMPLICIT, ODR_CONTEXT, 38, Z_AccessResponse_simpleForm,
668             odr_octetstring},
669         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_AccessResponse_externallyDefined,
670             odr_external},
671         {-1, -1, -1, -1, 0}
672     };
673     if (!odr_sequence_begin(o, p, sizeof(**p)))
674         return opt && odr_ok(o);
675     return
676         z_ReferenceId(o, &(*p)->referenceId, 1) &&
677         odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
678         odr_explicit(o, z_DiagRec, &(*p)->diagnostic, ODR_CONTEXT, 223, 1) &&
679 #ifdef Z_OTHERINFO
680         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
681 #endif
682         odr_sequence_end(o);
683 }
684
685 /* ------------------------ SCAN SERVICE -------------------- */
686
687 int z_AttributeList(ODR o, Z_AttributeList **p, int opt)
688 {
689     if (o->direction == ODR_DECODE)
690         *p = odr_malloc(o, sizeof(**p));
691     else if (!*p)
692         return opt;
693
694     odr_implicit_settag(o, ODR_CONTEXT, 44);
695     if (odr_sequence_of(o, z_AttributeElement, &(*p)->attributes,
696         &(*p)->num_attributes))
697         return 1;
698     *p = 0;
699     return opt && odr_ok(o);
700 }
701
702 /*
703  * This is a temporary hack. We don't know just *what* old version of the
704  * protocol willow uses, so we'll just patiently wait for them to update
705  */
706 static int willow_scan = 0;
707
708 int z_WillowAttributesPlusTerm(ODR o, Z_AttributesPlusTerm **p, int opt)
709 {
710     if (!*p && o->direction != ODR_DECODE)
711         return opt;
712     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 4))
713     {
714         o->t_class = -1;
715         return opt && odr_ok(o);
716     }
717     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 1))
718         return 0;
719     if (!odr_constructed_begin(o, p, ODR_UNIVERSAL, ODR_SEQUENCE))
720         return 0;
721     if (!odr_implicit_settag(o, ODR_CONTEXT, 44))
722         return 0;
723     if (o->direction == ODR_DECODE)
724         *p = odr_malloc(o, sizeof(**p));
725     if (!odr_sequence_of(o, z_AttributeElement, &(*p)->attributeList,
726         &(*p)->num_attributes))
727         return 0;
728     if (!odr_sequence_end(o) || !odr_sequence_end(o))
729         return 0;
730     if (!z_Term(o, &(*p)->term, 0))
731         return 0;
732     if (!odr_constructed_end(o))
733         return 0;
734     willow_scan = 1;
735     return 1;
736 }
737
738 int z_AlternativeTerm(ODR o, Z_AlternativeTerm **p, int opt)
739 {
740     if (o->direction == ODR_DECODE)
741         *p = odr_malloc(o, sizeof(**p));
742     else if (!*p)
743     {
744         o->t_class = -1;
745         return opt && odr_ok(o);
746     }
747
748     if (odr_sequence_of(o, z_AttributesPlusTerm, &(*p)->terms,
749         &(*p)->num_terms))
750         return 1;
751     *p = 0;
752     return opt && !o->error;
753 }
754
755 int z_OccurrenceByAttributes(ODR o, Z_OccurrenceByAttributes **p, int opt)
756 {
757     if (!odr_sequence_begin(o, p, sizeof(**p)))
758         return opt && odr_ok(o);
759     return
760         odr_explicit(o, z_AttributeList, &(*p)->attributes, ODR_CONTEXT, 1, 1)&&
761         odr_explicit(o, odr_integer, &(*p)->global, ODR_CONTEXT, 2, 1) &&
762         odr_sequence_end(o);
763 }
764
765 int z_TermInfo(ODR o, Z_TermInfo **p, int opt)
766 {
767     if (!odr_sequence_begin(o, p, sizeof(**p)))
768         return opt && odr_ok(o);
769     return
770         (willow_scan ? 
771             odr_implicit(o, z_Term, &(*p)->term, ODR_CONTEXT, 1, 0) :
772             z_Term(o, &(*p)->term, 0)) &&
773         z_AttributeList(o, &(*p)->suggestedAttributes, 1) &&
774         odr_implicit(o, z_AlternativeTerm, &(*p)->alternativeTerm,
775             ODR_CONTEXT, 4, 1) &&
776         odr_implicit(o, odr_integer, &(*p)->globalOccurrences, ODR_CONTEXT,
777             2, 1) &&
778         odr_implicit(o, z_OccurrenceByAttributes, &(*p)->byAttributes,
779             ODR_CONTEXT, 3, 1) &&
780         odr_sequence_end(o);
781 }
782
783 int z_Entry(ODR o, Z_Entry **p, int opt)
784 {
785     static Odr_arm arm[] =
786     {
787         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Entry_termInfo, z_TermInfo},
788         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_Entry_surrogateDiagnostic,
789             z_DiagRec},
790         {-1, -1, -1, -1, 0}
791     };
792
793     if (o->direction == ODR_DECODE)
794         *p = odr_malloc(o, sizeof(**p));
795
796     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
797         return 1;
798     *p = 0;
799     return opt && odr_ok(o);
800 }
801
802 int z_Entries(ODR o, Z_Entries **p, int opt)
803 {
804     if (o->direction == ODR_DECODE)
805         *p = odr_malloc(o, sizeof(**p));
806     else if (!*p)
807         return opt;
808
809     if (odr_sequence_of(o, z_Entry, &(*p)->entries,
810         &(*p)->num_entries))
811         return 1;
812     *p = 0;
813     return 0;
814 }
815
816 int z_DiagRecs(ODR o, Z_DiagRecs **p, int opt)
817 {
818     if (o->direction == ODR_DECODE)
819         *p = odr_malloc(o, sizeof(**p));
820     else if (!*p)
821         return opt;
822
823         if (odr_sequence_of(o, z_DiagRec, &(*p)->diagRecs,
824         &(*p)->num_diagRecs))
825         return 1;
826     *p = 0;
827     return 0;
828 }
829
830 int z_ListEntries(ODR o, Z_ListEntries **p, int opt)
831 {
832     static Odr_arm arm[] =
833     {
834         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ListEntries_entries, z_Entries},
835         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_ListEntries_nonSurrogateDiagnostics,
836             z_DiagRecs},
837         {-1, -1, -1, -1, 0}
838     };
839
840     if (o->direction == ODR_DECODE)
841         *p = odr_malloc(o, sizeof(**p));
842
843     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
844         return 1;
845     *p = 0;
846     return opt && odr_ok(o);
847 }
848
849 int z_ScanRequest(ODR o, Z_ScanRequest **p, int opt)
850 {
851     if (!odr_sequence_begin(o, p, sizeof(**p)))
852         return opt && odr_ok(o);
853     willow_scan = 0;
854     return
855         z_ReferenceId(o, &(*p)->referenceId, 1) &&
856         odr_implicit_settag(o, ODR_CONTEXT, 3) &&
857         odr_sequence_of(o, z_DatabaseName, &(*p)->databaseNames,
858             &(*p)->num_databaseNames) &&
859         odr_oid(o, &(*p)->attributeSet, 1) &&
860         (z_AttributesPlusTerm(o, &(*p)->termListAndStartPoint, 1) ?
861             ((*p)->termListAndStartPoint ? 1 : 
862         z_WillowAttributesPlusTerm(o, &(*p)->termListAndStartPoint, 0)) : 0) &&
863         odr_implicit(o, odr_integer, &(*p)->stepSize, ODR_CONTEXT, 5, 1) &&
864         odr_implicit(o, odr_integer, &(*p)->numberOfTermsRequested,
865             ODR_CONTEXT, 6, 0) &&
866         odr_implicit(o, odr_integer, &(*p)->preferredPositionInResponse,
867             ODR_CONTEXT, 7, 1) &&
868         odr_sequence_end(o);
869 }
870
871 int z_ScanResponse(ODR o, Z_ScanResponse **p, int opt)
872 {
873     if (!odr_sequence_begin(o, p, sizeof(**p)))
874         return opt && odr_ok(o);
875     return
876         z_ReferenceId(o, &(*p)->referenceId, 1) &&
877         odr_implicit(o, odr_integer, &(*p)->stepSize, ODR_CONTEXT, 3, 1) &&
878         odr_implicit(o, odr_integer, &(*p)->scanStatus, ODR_CONTEXT, 4, 0) &&
879         odr_implicit(o, odr_integer, &(*p)->numberOfEntriesReturned,
880             ODR_CONTEXT, 5, 0) &&
881         odr_implicit(o, odr_integer, &(*p)->positionOfTerm, ODR_CONTEXT, 6, 1)&&
882         odr_explicit(o, z_ListEntries, &(*p)->entries, ODR_CONTEXT, 7, 1) &&
883         odr_implicit(o, odr_oid, &(*p)->attributeSet, ODR_CONTEXT, 8, 1) &&
884         odr_sequence_end(o);
885 }
886
887 /* ------------------------ SEARCHRESPONSE ----------------*/
888
889 int z_NumberOfRecordsReturned(ODR o, int **p, int opt)
890 {
891     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 24, opt);
892 }
893
894 int z_NextResultSetPosition(ODR o, int **p, int opt)
895 {
896     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 25, opt);
897 }
898
899 int z_PresentStatus(ODR o, int **p, int opt)
900 {
901     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 27, opt);
902 }
903
904 int z_SearchResponse(ODR o, Z_SearchResponse **p, int opt)
905 {
906     Z_SearchResponse *pp;
907
908     if (!odr_sequence_begin(o, p, sizeof(**p)))
909         return opt && odr_ok(o);
910     pp = *p;
911     return
912         z_ReferenceId(o, &pp->referenceId, 1) &&
913         odr_implicit(o, odr_integer, &pp->resultCount, ODR_CONTEXT, 23, 0) &&
914         z_NumberOfRecordsReturned(o, &pp->numberOfRecordsReturned, 0) &&
915         z_NextResultSetPosition(o, &pp->nextResultSetPosition, 0) &&
916         odr_implicit(o, odr_bool, &pp->searchStatus, ODR_CONTEXT, 22, 0) &&
917         odr_implicit(o, odr_integer, &pp->resultSetStatus, ODR_CONTEXT, 26, 1) &&
918         z_PresentStatus(o, &pp->presentStatus, 1) &&
919         z_Records(o, &pp->records, 1) &&
920 #ifdef Z_OTHERINFO
921         odr_implicit(o, z_OtherInformation, &(*p)->additionalSearchInfo,
922             ODR_CONTEXT, 203, 1) &&
923         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
924 #endif
925         odr_sequence_end(o);
926 }
927
928 /* --------------------- PRESENT SERVICE ---------------------- */
929
930 int z_PresentRequest(ODR o, Z_PresentRequest **p, int opt)
931 {
932     Z_PresentRequest *pp;
933
934     if (!odr_sequence_begin(o, p, sizeof(**p)))
935         return opt && odr_ok(o);
936     pp = *p;
937     return
938         z_ReferenceId(o, &pp->referenceId, 1) &&
939         z_ResultSetId(o, &pp->resultSetId, 0) &&
940         odr_implicit(o, odr_integer, &pp->resultSetStartPoint, ODR_CONTEXT,
941             30, 0) &&
942         odr_implicit(o, odr_integer, &pp->numberOfRecordsRequested, ODR_CONTEXT,
943             29, 0) &&
944         z_ElementSetNames(o, &pp->elementSetNames, 1) &&
945         z_PreferredRecordSyntax(o, &pp->preferredRecordSyntax, 1) &&
946         odr_sequence_end(o);
947 }
948
949 int z_PresentResponse(ODR o, Z_PresentResponse **p, int opt)
950 {
951     Z_PresentResponse *pp;
952
953     if (!odr_sequence_begin(o, p, sizeof(**p)))
954         return opt && odr_ok(o);
955     pp = *p;
956     return
957         z_ReferenceId(o, &pp->referenceId, 1) &&
958         z_NumberOfRecordsReturned(o, &pp->numberOfRecordsReturned, 0) &&
959         z_NextResultSetPosition(o, &pp->nextResultSetPosition, 0) &&
960         z_PresentStatus(o, &pp->presentStatus, 0) &&
961         z_Records(o, &pp->records, 1) &&
962         odr_sequence_end(o);
963 }
964
965 /* ----------------------DELETE -------------------------- */
966
967 int z_DeleteSetStatus(ODR o, int **p, int opt)
968 {
969     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 33, opt);
970 }
971
972 int z_ListStatus(ODR o, Z_ListStatus **p, int opt)
973 {
974     if (!odr_sequence_begin(o, p, sizeof(**p)))
975         return opt && odr_ok(o);
976     return
977         z_ResultSetId(o, &(*p)->id, 0) &&
978         z_DeleteSetStatus(o, &(*p)->status, 0) &&
979         odr_sequence_end(o);
980 }
981
982 int z_DeleteResultSetRequest(ODR o, Z_DeleteResultSetRequest **p, int opt)
983 {
984     if (!odr_sequence_begin(o, p, sizeof(**p)))
985         return opt && odr_ok(o);
986     return
987         z_ReferenceId(o, &(*p)->referenceId, 1) &&
988         odr_implicit(o, odr_integer, &(*p)->deleteFunction, ODR_CONTEXT, 32,
989             0) &&
990         (odr_sequence_of(o, z_ListStatus, &(*p)->resultSetList,
991             &(*p)->num_ids) || odr_ok(o)) &&
992 #ifdef Z_OTHERINFO
993         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
994 #endif
995         odr_sequence_end(o);
996 }
997
998 int z_DeleteResultSetResponse(ODR o, Z_DeleteResultSetResponse **p, int opt)
999 {
1000     if (!odr_sequence_begin(o, p, sizeof(**p)))
1001         return opt && odr_ok(o);
1002     return
1003         z_ReferenceId(o, &(*p)->referenceId, 1) &&
1004         odr_implicit(o, z_DeleteSetStatus, &(*p)->deleteOperationStatus,
1005             ODR_CONTEXT, 0, 1) &&
1006         odr_implicit_settag(o, ODR_CONTEXT, 1) &&
1007         (odr_sequence_of(o, z_ListStatus, &(*p)->deleteListStatuses,
1008             &(*p)->num_statuses) || odr_ok(o)) &&
1009         odr_implicit(o, odr_integer, &(*p)->numberNotDeleted, ODR_CONTEXT,
1010             34, 1) &&
1011         odr_implicit_settag(o, ODR_CONTEXT, 35) &&
1012         (odr_sequence_of(o, z_ListStatus, &(*p)->bulkStatuses,
1013             &(*p)->num_bulkStatuses) || odr_ok(o)) &&
1014         odr_implicit(o, odr_visiblestring, &(*p)->deleteMessage, ODR_CONTEXT,
1015             36, 1) &&
1016 #ifdef Z_OTHERINFO
1017         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1018 #endif
1019         odr_sequence_end(o);
1020 }
1021
1022 /* ------------------------ APDU ------------------------- */
1023
1024 int z_APDU(ODR o, Z_APDU **p, int opt)
1025 {
1026     static Odr_arm arm[] =
1027     {
1028         {ODR_IMPLICIT, ODR_CONTEXT, 20, Z_APDU_initRequest, z_InitRequest},
1029         {ODR_IMPLICIT, ODR_CONTEXT, 21, Z_APDU_initResponse, z_InitResponse},
1030         {ODR_IMPLICIT, ODR_CONTEXT, 22, Z_APDU_searchRequest, z_SearchRequest},
1031         {ODR_IMPLICIT, ODR_CONTEXT, 23, Z_APDU_searchResponse,
1032             z_SearchResponse},
1033         {ODR_IMPLICIT, ODR_CONTEXT, 24, Z_APDU_presentRequest,
1034             z_PresentRequest},
1035         {ODR_IMPLICIT, ODR_CONTEXT, 25, Z_APDU_presentResponse,
1036             z_PresentResponse},
1037         {ODR_IMPLICIT, ODR_CONTEXT, 26, Z_APDU_deleteResultSetRequest,
1038             z_DeleteResultSetRequest},
1039         {ODR_IMPLICIT, ODR_CONTEXT, 27, Z_APDU_deleteResultSetResponse,
1040             z_DeleteResultSetResponse},
1041         {ODR_IMPLICIT, ODR_CONTEXT, 30, Z_APDU_resourceControlRequest,
1042             z_ResourceControlRequest},
1043         {ODR_IMPLICIT, ODR_CONTEXT, 31, Z_APDU_resourceControlResponse,
1044             z_ResourceControlResponse},
1045         {ODR_IMPLICIT, ODR_CONTEXT, 32, Z_APDU_triggerResourceControlRequest,
1046             z_TriggerResourceControlRequest},
1047         {ODR_IMPLICIT, ODR_CONTEXT, 35, Z_APDU_scanRequest, z_ScanRequest},
1048         {ODR_IMPLICIT, ODR_CONTEXT, 36, Z_APDU_scanResponse, z_ScanResponse},
1049
1050         {-1, -1, -1, -1, 0}
1051     };
1052
1053     if (o->direction == ODR_DECODE)
1054         *p = odr_malloc(o, sizeof(**p));
1055     if (!odr_choice(o, arm, &(*p)->u, &(*p)->which))
1056     {
1057         if (o->direction == ODR_DECODE)
1058             *p = 0;
1059         return opt && odr_ok(o);
1060     }
1061     return 1;
1062 }