Added memory management.
[yaz-moved-to-github.git] / asn / proto.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: proto.c,v $
7  * Revision 1.11  1995-03-17 10:17:25  quinn
8  * Added memory management.
9  *
10  * Revision 1.10  1995/03/15  11:17:40  quinn
11  * Fixed some return-checks from choice.. need better ay to handle those..
12  *
13  * Revision 1.9  1995/03/15  08:37:06  quinn
14  * Fixed protocol bugs.
15  *
16  * Revision 1.8  1995/03/14  16:59:24  quinn
17  * Fixed OPTIONAL flag in attributeelement
18  *
19  * Revision 1.7  1995/03/07  16:29:33  quinn
20  * Added authentication stuff.
21  *
22  * Revision 1.6  1995/03/01  14:46:03  quinn
23  * Fixed protocol bug in 8777query.
24  *
25  * Revision 1.5  1995/02/14  11:54:22  quinn
26  * Fixing include.
27  *
28  * Revision 1.4  1995/02/10  15:54:30  quinn
29  * Small adjustments.
30  *
31  * Revision 1.3  1995/02/09  15:51:39  quinn
32  * Works better now.
33  *
34  * Revision 1.2  1995/02/06  21:26:07  quinn
35  * Repaired this evening's damages..
36  *
37  * Revision 1.1  1995/02/06  16:44:47  quinn
38  * First hack at Z/SR protocol
39  *
40  */
41
42 #include <odr.h>
43
44 #include <proto.h>
45
46 /* ---------------------- GLOBAL DEFS ------------------- */
47
48 int z_ReferenceId(ODR o, Z_ReferenceId **p, int opt)
49 {
50     return odr_implicit(o, odr_octetstring, (Odr_oct**) p, ODR_CONTEXT, 2, opt);
51 }
52
53 int z_DatabaseName(ODR o, Z_DatabaseName **p, int opt)
54 {
55     return odr_implicit(o, odr_visiblestring, (char **) p, ODR_CONTEXT, 105,
56         opt);
57 }
58
59 int z_ResultSetId(ODR o, char **p, int opt)
60 {
61     return odr_implicit(o, odr_visiblestring, (char **) p, ODR_CONTEXT, 31,
62         opt);
63 }
64
65 int z_UserInformationField(ODR o, Z_UserInformationField **p, int opt)
66 {
67     return odr_explicit(o, odr_external, (Odr_external **)p, ODR_CONTEXT,
68         11, opt);
69 }
70
71 /* ---------------------- INITIALIZE SERVICE ------------------- */
72
73 int z_InitRequest(ODR o, Z_InitRequest **p, int opt)
74 {
75     Z_InitRequest *pp;
76
77     if (!odr_sequence_begin(o, p, sizeof(**p)))
78         return opt;
79     pp = *p;
80     return
81         z_ReferenceId(o, &pp->referenceId, 1) &&
82         odr_implicit(o, odr_bitstring, &pp->protocolVersion, ODR_CONTEXT, 
83             3, 0) &&
84         odr_implicit(o, odr_bitstring, &pp->options, ODR_CONTEXT, 4, 0) &&
85         odr_implicit(o, odr_integer, &pp->preferredMessageSize, ODR_CONTEXT,
86             5, 0) &&
87         odr_implicit(o, odr_integer, &pp->maximumRecordSize, ODR_CONTEXT,
88             6, 0) &&
89         odr_explicit(o, odr_any, &pp->idAuthentication, ODR_CONTEXT,
90             7, 1) &&
91         odr_implicit(o, odr_visiblestring, &pp->implementationId, ODR_CONTEXT,
92             110, 1) &&
93         odr_implicit(o, odr_visiblestring, &pp->implementationName, ODR_CONTEXT,
94             111, 1) &&
95         odr_implicit(o, odr_visiblestring, &pp->implementationVersion,
96             ODR_CONTEXT, 112, 1) &&
97         z_UserInformationField(o, &pp->userInformationField, 1) &&
98         odr_sequence_end(o);
99 }
100
101 int z_InitResponse(ODR o, Z_InitResponse **p, int opt)
102 {
103     Z_InitResponse *pp;
104
105     if (!odr_sequence_begin(o, p, sizeof(**p)))
106         return opt;
107     pp = *p;
108     return
109         z_ReferenceId(o, &pp->referenceId, 1) &&
110         odr_implicit(o, odr_bitstring, &pp->protocolVersion, ODR_CONTEXT, 
111             3, 0) &&
112         odr_implicit(o, odr_bitstring, &pp->options, ODR_CONTEXT, 4, 0) &&
113         odr_implicit(o, odr_integer, &pp->preferredMessageSize, ODR_CONTEXT,
114             5, 0) &&
115         odr_implicit(o, odr_integer, &pp->maximumRecordSize, ODR_CONTEXT,
116             6, 0) &&
117         odr_implicit(o, odr_bool, &pp->result, ODR_CONTEXT, 12, 0) &&
118         odr_implicit(o, odr_visiblestring, &pp->implementationId, ODR_CONTEXT,
119             110, 1) &&
120         odr_implicit(o, odr_visiblestring, &pp->implementationName, ODR_CONTEXT,
121             111, 1) &&
122         odr_implicit(o, odr_visiblestring, &pp->implementationVersion,
123             ODR_CONTEXT, 112, 1) &&
124         z_UserInformationField(o, &pp->userInformationField, 1) &&
125         odr_sequence_end(o);
126 }
127
128 int z_NSRAuthentication(ODR o, Z_NSRAuthentication **p, int opt)
129 {
130     if (!odr_sequence_begin(o, p, sizeof(**p)))
131         return opt;
132     return
133         odr_visiblestring(o, &(*p)->user, 0) &&
134         odr_visiblestring(o, &(*p)->password, 0) &&
135         odr_visiblestring(o, &(*p)->account, 0) &&
136         odr_sequence_end(o);
137 }
138
139 int z_StrAuthentication(ODR o, char **p, int opt)
140 {
141     return odr_visiblestring(o, p, opt);
142 }
143
144 /* ------------------------ SEARCH SERVICE ----------------------- */
145
146 int z_ElementSetName(ODR o, char **p, int opt)
147 {
148     return odr_implicit(o, odr_visiblestring, (char**) p, ODR_CONTEXT, 103,
149         opt);
150 }
151
152 int z_PreferredRecordSyntax(ODR o, Z_PreferredRecordSyntax **p, int opt)
153 {
154     return odr_implicit(o, odr_oid, (Odr_oid**) p, ODR_CONTEXT, 104, opt);
155 }
156
157 int z_DatabaseSpecificUnit(ODR o, Z_DatabaseSpecificUnit **p, int opt)
158 {
159     if (!odr_sequence_begin(o, p, sizeof(**p)))
160         return opt;
161     return
162         z_DatabaseName(o, &(*p)->databaseName, 0) &&
163         z_ElementSetName(o, &(*p)->elementSetName, 0) &&
164         odr_sequence_end(o);
165 }
166
167 int z_DatabaseSpecific(ODR o, Z_DatabaseSpecific **p, int opt)
168 {
169     if (o->direction == ODR_DECODE)
170         *p = odr_malloc(o, sizeof(**p));
171     else if (!*p)
172         return opt;
173
174     odr_implicit_settag(o, ODR_CONTEXT, 1);
175     if (odr_sequence_of(o, z_DatabaseSpecificUnit, &(*p)->elements,
176         &(*p)->num_elements))
177         return 1;
178     *p = 0;
179     return 0;
180 }
181
182 int z_ElementSetNames(ODR o, Z_ElementSetNames **p, int opt)
183 {
184     static Odr_arm arm[] =
185     {
186         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_ElementSetNames_generic,
187             z_ElementSetName},
188         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ElementSetNames_databaseSpecific,
189             z_DatabaseSpecific},
190         {-1, -1, -1, -1, 0}
191     };
192
193     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 19))
194         return opt;
195
196     if (o->direction == ODR_DECODE)
197         *p = odr_malloc(o, sizeof(**p));
198
199     if (odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
200         odr_constructed_end(o))
201         return 1;
202     *p = 0;
203     return 0;
204 }
205
206 /* ----------------------- RPN QUERY -----------------------*/
207
208 int z_AttributeElement(ODR o, Z_AttributeElement **p, int opt)
209 {
210     if (!odr_sequence_begin(o, p, sizeof(**p)))
211         return opt;
212     return
213         odr_implicit(o, odr_integer, &(*p)->attributeType, ODR_CONTEXT,
214             120, 0) &&
215         odr_implicit(o, odr_integer, &(*p)->attributeValue, ODR_CONTEXT,
216             121, 0) &&
217         odr_sequence_end(o);
218 }
219
220 int z_AttributesPlusTerm(ODR o, Z_AttributesPlusTerm **p, int opt)
221 {
222     if (!(odr_implicit_settag(o, ODR_CONTEXT, 102) &&
223         odr_sequence_begin(o, p, sizeof(**p))))
224         return opt;
225     return
226         odr_implicit_settag(o, ODR_CONTEXT, 44) &&
227         odr_sequence_of(o, z_AttributeElement, &(*p)->attributeList,
228             &(*p)->num_attributes) &&
229         odr_implicit(o, odr_octetstring, &(*p)->term, ODR_CONTEXT, 45, 0) &&
230         odr_sequence_end(o);
231 }
232
233 int z_Operator(ODR o, Z_Operator **p, int opt)
234 {
235     static Odr_arm arm[] =
236     {
237         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_Operator_and, odr_null},
238         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Operator_or, odr_null},
239         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_Operator_and_not, odr_null},
240         {-1, -1, -1, -1, 0}
241     };
242     int dummy = 999;
243
244     if (!*p && o->direction != ODR_DECODE)
245         return opt;
246     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 46))
247         return opt;
248     if (o->direction == ODR_DECODE)
249         *p = odr_malloc(o, sizeof(**p));
250     else
251         (*p)->u.and = &dummy;
252
253     if (odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
254         odr_constructed_end(o))
255         return 1;
256     *p = 0;
257     return opt && !o->error;
258 }
259
260 int z_Operand(ODR o, Z_Operand **p, int opt)
261 {
262     static Odr_arm arm[] =
263     {
264         {-1, -1, -1, Z_Operand_APT, z_AttributesPlusTerm},
265         {-1, -1, -1, Z_Operand_resultSetId, z_ResultSetId},
266         {-1, -1, -1, -1, 0}
267     };
268
269     if (o->direction ==ODR_DECODE)
270         *p = odr_malloc(o, sizeof(**p));
271     else if (!*p)
272         return opt;
273     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
274         return 1;
275     *p = 0;
276     return opt && !o->error;
277 }
278
279 int z_RPNStructure(ODR o, Z_RPNStructure **p, int opt);
280
281 int z_Complex(ODR o, Z_Complex **p, int opt)
282 {
283     if (!odr_sequence_begin(o, p, sizeof(**p)))
284         return opt;
285     return
286         z_RPNStructure(o, &(*p)->s1, 0) &&
287         z_RPNStructure(o, &(*p)->s2, 0) &&
288         z_Operator(o, &(*p)->operator, 0) &&
289         odr_sequence_end(o);
290 }
291
292 int z_RPNStructure(ODR o, Z_RPNStructure **p, int opt)
293 {
294     static Odr_arm arm[] = 
295     {
296         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_RPNStructure_simple, z_Operand},
297         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_RPNStructure_complex, z_Complex},
298         {-1 -1, -1, -1, 0}
299     };
300
301     if (o->direction == ODR_DECODE)
302         *p = odr_malloc(o, sizeof(**p));
303     else if (!*p)
304         return opt;
305     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
306         return 1;
307     *p = 0;
308     return opt && !o->error;
309 }
310
311 int z_RPNQuery(ODR o, Z_RPNQuery **p, int opt)
312 {
313     if (!odr_sequence_begin(o, p, sizeof(**p)))
314         return opt;
315     return
316         odr_oid(o, &(*p)->attributeSetId, 0) &&
317         z_RPNStructure(o, &(*p)->RPNStructure, 0) &&
318         odr_sequence_end(o);
319 }
320
321 /* -----------------------END RPN QUERY ----------------------- */
322
323 int z_Query(ODR o, Z_Query **p, int opt)
324 {
325     static Odr_arm arm[] = 
326     {
327         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Query_type_1, z_RPNQuery},
328         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_Query_type_2, odr_octetstring},
329         {-1, -1, -1, -1, 0}
330     };
331
332     if (o->direction == ODR_DECODE)
333         *p = odr_malloc(o, sizeof(**p));
334     else if (!*p)
335         return opt;
336     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
337         return 1;
338     *p = 0;
339     return opt && !o->error;
340 }
341
342 int z_SearchRequest(ODR o, Z_SearchRequest **p, int opt)
343 {
344     Z_SearchRequest *pp;
345
346     if (!odr_sequence_begin(o, p, sizeof(**p)))
347         return opt;
348     pp = *p;
349     return
350         z_ReferenceId(o, &pp->referenceId, 1) &&
351         odr_implicit(o, odr_integer, &pp->smallSetUpperBound, ODR_CONTEXT,
352             13, 0) &&
353         odr_implicit(o, odr_integer, &pp->largeSetLowerBound, ODR_CONTEXT,
354             14, 0) &&
355         odr_implicit(o, odr_integer, &pp->mediumSetPresentNumber, ODR_CONTEXT,
356             15, 0) &&
357         odr_implicit(o, odr_bool, &pp->replaceIndicator, ODR_CONTEXT, 16, 1) &&
358         odr_implicit(o, odr_visiblestring, &pp->resultSetName, ODR_CONTEXT,
359             17, 9) &&
360         odr_implicit_settag(o, ODR_CONTEXT, 18) &&
361         odr_sequence_of(o, z_DatabaseName, &pp->databaseNames,
362             &pp->num_databaseNames) &&
363         odr_implicit(o, z_ElementSetNames, &pp->smallSetElementSetNames,
364             ODR_CONTEXT, 100, 1) &&
365         odr_implicit(o, z_ElementSetNames, &pp->mediumSetElementSetNames,
366             ODR_CONTEXT, 101, 1) &&
367         z_PreferredRecordSyntax(o, &pp->preferredRecordSyntax, 1) &&
368         odr_explicit(o, z_Query, &pp->query, ODR_CONTEXT, 21, 0) &&
369         odr_sequence_end(o);
370 }
371
372 /* ------------------------ RECORD ------------------------- */
373
374 int z_DatabaseRecord(ODR o, Z_DatabaseRecord **p, int opt)
375 {
376     return odr_external(o, (Odr_external **) p, opt);
377 }
378
379 int z_DiagRec(ODR o, Z_DiagRec **p, int opt)
380 {
381     if (!odr_sequence_begin(o, p, sizeof(**p)))
382         return opt;
383     return
384         odr_oid(o, &(*p)->diagnosticSetId, 1) &&       /* SHOULD NOT BE OPT */
385         odr_integer(o, &(*p)->condition, 0) &&
386         (odr_visiblestring(o, &(*p)->addinfo, 0) ||
387         odr_implicit(o, odr_cstring, &(*p)->addinfo, ODR_CONTEXT, ODR_VISIBLESTRING, 1)) &&
388         odr_sequence_end(o);
389 }
390
391 int z_NamePlusRecord(ODR o, Z_NamePlusRecord **p, int opt)
392 {
393     static Odr_arm arm[] =
394     {
395         {ODR_EXPLICIT, ODR_CONTEXT, 1, Z_NamePlusRecord_databaseRecord,
396             z_DatabaseRecord},
397         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_NamePlusRecord_surrogateDiagnostic,
398             z_DiagRec},
399         {-1, -1, -1, -1, 0}
400     };
401
402     if (!odr_sequence_begin(o, p, sizeof(**p)))
403         return opt;
404     return
405         odr_implicit(o, z_DatabaseName, &(*p)->databaseName, ODR_CONTEXT,
406             0, 1) &&
407         odr_constructed_begin(o, &(*p)->u, ODR_CONTEXT, 1) &&
408         odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
409         odr_constructed_end(o) &&
410         odr_sequence_end(o);
411 }
412
413 int z_NamePlusRecordList(ODR o, Z_NamePlusRecordList **p, int opt)
414 {
415     if (o->direction == ODR_DECODE)
416         *p = odr_malloc(o, sizeof(**p));
417     if (odr_sequence_of(o, z_NamePlusRecord, &(*p)->records,
418         &(*p)->num_records))
419         return 1;
420     *p = 0;
421     return 0;
422 }
423
424 int z_Records(ODR o, Z_Records **p, int opt)
425 {
426     Odr_arm arm[] = 
427     {
428         {ODR_IMPLICIT, ODR_CONTEXT, 28, Z_Records_DBOSD, z_NamePlusRecordList},
429         {ODR_IMPLICIT, ODR_CONTEXT, 130, Z_Records_NSD, z_DiagRec},
430         {-1, -1, -1, -1, 0}
431     };
432
433     if (o->direction == ODR_DECODE)
434         *p = odr_malloc(o, sizeof(**p));
435     else if (!*p)
436         return opt;
437     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
438         return 1;
439     *p = 0;
440     return opt && !o->error;
441 }
442
443 /* ------------------------ SEARCHRESPONSE ----------------*/
444
445 int z_NumberOfRecordsReturned(ODR o, int **p, int opt)
446 {
447     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 24, opt);
448 }
449
450 int z_NextResultSetPosition(ODR o, int **p, int opt)
451 {
452     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 25, opt);
453 }
454
455 int z_PresentStatus(ODR o, int **p, int opt)
456 {
457     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 27, opt);
458 }
459
460 int z_SearchResponse(ODR o, Z_SearchResponse **p, int opt)
461 {
462     Z_SearchResponse *pp;
463
464     if (!odr_sequence_begin(o, p, sizeof(**p)))
465         return opt;
466     pp = *p;
467     return
468         z_ReferenceId(o, &pp->referenceId, 1) &&
469         odr_implicit(o, odr_integer, &pp->resultCount, ODR_CONTEXT, 23, 0) &&
470         z_NumberOfRecordsReturned(o, &pp->numberOfRecordsReturned, 0) &&
471         z_NextResultSetPosition(o, &pp->nextResultSetPosition, 0) &&
472         odr_implicit(o, odr_bool, &pp->searchStatus, ODR_CONTEXT, 22, 0) &&
473         odr_implicit(o, odr_integer, &pp->resultSetStatus, ODR_CONTEXT, 26, 1) &&
474         z_PresentStatus(o, &pp->presentStatus, 1) &&
475         z_Records(o, &pp->records, 1) &&
476         odr_sequence_end(o);
477 }
478
479 /* --------------------- PRESENT SERVICE ---------------------- */
480
481 int z_PresentRequest(ODR o, Z_PresentRequest **p, int opt)
482 {
483     Z_PresentRequest *pp;
484
485     if (!odr_sequence_begin(o, p, sizeof(**p)))
486         return opt;
487     pp = *p;
488     return
489         z_ReferenceId(o, &pp->referenceId, 1) &&
490         z_ResultSetId(o, &pp->resultSetId, 0) &&
491         odr_implicit(o, odr_integer, &pp->resultSetStartPoint, ODR_CONTEXT,
492             30, 0) &&
493         odr_implicit(o, odr_integer, &pp->numberOfRecordsRequested, ODR_CONTEXT,
494             29, 0) &&
495         z_ElementSetNames(o, &pp->elementSetNames, 1) &&
496         z_PreferredRecordSyntax(o, &pp->preferredRecordSyntax, 1) &&
497         odr_sequence_end(o);
498 }
499
500 int z_PresentResponse(ODR o, Z_PresentResponse **p, int opt)
501 {
502     Z_PresentResponse *pp;
503
504     if (!odr_sequence_begin(o, p, sizeof(**p)))
505         return opt;
506     pp = *p;
507     return
508         z_ReferenceId(o, &pp->referenceId, 1) &&
509         z_NumberOfRecordsReturned(o, &pp->numberOfRecordsReturned, 0) &&
510         z_NextResultSetPosition(o, &pp->nextResultSetPosition, 0) &&
511         z_PresentStatus(o, &pp->presentStatus, 0) &&
512         z_Records(o, &pp->records, 1) &&
513         odr_sequence_end(o);
514 }
515
516 /* ------------------------ APDU ------------------------- */
517
518 int z_APDU(ODR o, Z_APDU **p, int opt)
519 {
520     static Odr_arm arm[] =
521     {
522         {ODR_IMPLICIT, ODR_CONTEXT, 20, Z_APDU_initRequest, z_InitRequest},
523         {ODR_IMPLICIT, ODR_CONTEXT, 21, Z_APDU_initResponse, z_InitResponse},
524         {ODR_IMPLICIT, ODR_CONTEXT, 22, Z_APDU_searchRequest, z_SearchRequest},
525         {ODR_IMPLICIT, ODR_CONTEXT, 23, Z_APDU_searchResponse, z_SearchResponse},
526         {ODR_IMPLICIT, ODR_CONTEXT, 24, Z_APDU_presentRequest, z_PresentRequest},
527         {ODR_IMPLICIT, ODR_CONTEXT, 25, Z_APDU_presentResponse, z_PresentResponse},
528
529         {-1, -1, -1, -1, 0}
530     };
531
532     if (o->direction == ODR_DECODE)
533         *p = odr_malloc(o, sizeof(**p));
534     if (!odr_choice(o, arm, &(*p)->u, &(*p)->which))
535     {
536         if (o->direction == ODR_DECODE)
537             *p = 0;
538         return opt && !o->error;
539     }
540     return 1;
541 }