Added refernceId handling for other services.
[yazpp-moved-to-github.git] / src / yaz-z-server.cpp
1 /*
2  * Copyright (c) 2000-2001, Index Data.
3  * See the file LICENSE for details.
4  * 
5  * $Log: yaz-z-server.cpp,v $
6  * Revision 1.12  2001-04-25 19:40:18  adam
7  * Added refernceId handling for other services.
8  *
9  * Revision 1.11  2001/04/12 15:12:10  heikki
10  * minor ursula stuff
11  *
12  * Revision 1.10  2001/04/04 14:02:49  adam
13  * URSULA / Z-ruth service.
14  *
15  * Revision 1.9  2001/03/29 15:14:26  adam
16  * Minor updates.
17  *
18  * Revision 1.8  2001/03/27 14:47:45  adam
19  * New server facility scheme.
20  *
21  * Revision 1.7  2001/03/26 14:43:49  adam
22  * New threaded PDU association.
23  *
24  * Revision 1.6  2001/01/29 11:18:24  adam
25  * Server sets OPTIONS search and present.
26  *
27  * Revision 1.5  2000/10/24 12:29:57  adam
28  * Fixed bug in proxy where a Yaz_ProxyClient could be owned by
29  * two Yaz_Proxy's (fatal).
30  *
31  * Revision 1.4  2000/10/11 11:58:17  adam
32  * Moved header files to include/yaz++. Switched to libtool and automake.
33  * Configure script creates yaz++-config script.
34  *
35  * Revision 1.3  2000/09/21 21:43:20  adam
36  * Better high-level server API.
37  *
38  * Revision 1.2  2000/09/12 12:09:53  adam
39  * More work on high-level server.
40  *
41  * Revision 1.1  2000/09/08 10:23:42  adam
42  * Added skeleton of yaz-z-server.
43  *
44  */
45
46 #include <yaz/log.h>
47 #include <yaz++/yaz-z-server.h>
48
49 Yaz_Z_Server::Yaz_Z_Server(IYaz_PDU_Observable *the_PDU_Observable)
50     : Yaz_Z_Assoc(the_PDU_Observable)
51 {
52     m_facilities = 0;
53 }
54
55 Yaz_Z_Server::~Yaz_Z_Server()
56 {
57     facility_reset();
58 }
59
60 void Yaz_Z_Server::facility_reset ()
61 {
62     Yaz_Z_Server_Facility_Info *p = m_facilities;
63     while (p)
64     {
65         Yaz_Z_Server_Facility_Info *p_next = p->m_next;
66
67         delete [] p->m_name;
68         delete p;
69         p = p_next;
70     }
71     m_facilities = 0;
72 }
73
74 void Yaz_Z_Server::facility_add(IYaz_Server_Facility *facility,
75                                 const char *name)
76 {
77     Yaz_Z_Server_Facility_Info **p = &m_facilities;
78     while (*p)
79         p = &(*p)->m_next;
80
81     *p = new Yaz_Z_Server_Facility_Info;
82
83     (*p)->m_next = 0;
84     (*p)->m_name = new char [strlen(name)+1];
85     strcpy ((*p)->m_name, name);
86     (*p)->m_facility = facility;
87 }
88
89 void Yaz_Z_Server::recv_Z_PDU (Z_APDU *apdu_request)
90 {   
91     Yaz_Z_Server_Facility_Info *f = m_facilities;
92     
93     if (apdu_request->which == Z_APDU_initRequest)
94     {
95         Z_APDU *apdu_response = create_Z_PDU(Z_APDU_initResponse);
96
97         Z_InitRequest *req = apdu_request->u.initRequest;
98         Z_InitResponse *resp = apdu_response->u.initResponse;
99         
100         if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_1))
101         {
102             ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_1);
103         }
104         if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_2))
105         {
106             ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_2);
107         }
108         if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_3))
109         {
110             ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_3);
111         }
112         while (f)
113         {
114             f->m_facility->init(this, req, resp);
115             f = f->m_next;
116         }
117         transfer_referenceId(apdu_request, apdu_response);
118         send_Z_PDU(apdu_response);
119     }
120     else
121     {
122         f = m_facilities;
123         int taken = 0;
124         while (f)
125         {
126             taken = f->m_facility->recv(this, apdu_request);
127             if (taken)
128                 break;
129             f = f->m_next;
130         }
131         if (!taken)
132         {
133             yaz_log (LOG_LOG, "unhandled request = %d", apdu_request->which);
134             delete this;
135         }
136     }
137 }
138
139 /*
140  * database record.
141  */
142 void Yaz_Z_ServerUtility::create_databaseRecord (
143     ODR odr, Z_NamePlusRecord *rec, const char *dbname, int format,
144     const void *buf, int len)
145 {
146     rec->databaseName = dbname ? odr_strdup (odr, dbname) : 0;
147     rec->which = Z_NamePlusRecord_databaseRecord;
148     rec->u.databaseRecord = z_ext_record (odr, format,
149                                           (const char *) buf, len);
150 }
151
152 /*
153  * surrogate diagnostic.
154  */
155 void Yaz_Z_ServerUtility::create_surrogateDiagnostics(
156     ODR odr, Z_NamePlusRecord *rec, const char *dbname,
157     int error, char *const addinfo)
158 {
159     int oid[OID_SIZE];
160     int *err = (int *)odr_malloc (odr, sizeof(*err));
161     oident bib1;
162     Z_DiagRec *drec = (Z_DiagRec *)odr_malloc (odr, sizeof(*drec));
163     Z_DefaultDiagFormat *dr = (Z_DefaultDiagFormat *)
164         odr_malloc (odr, sizeof(*dr));
165     
166     bib1.proto = PROTO_Z3950;
167     bib1.oclass = CLASS_DIAGSET;
168     bib1.value = VAL_BIB1;
169
170     yaz_log(LOG_DEBUG, "SurrogateDiagnotic: %d -- %s", error, addinfo);
171     *err = error;
172     rec->databaseName = dbname ? odr_strdup (odr, dbname) : 0;
173     rec->which = Z_NamePlusRecord_surrogateDiagnostic;
174     rec->u.surrogateDiagnostic = drec;
175     drec->which = Z_DiagRec_defaultFormat;
176     drec->u.defaultFormat = dr;
177     dr->diagnosticSetId = odr_oiddup (odr,
178                                       oid_ent_to_oid(&bib1, oid));
179     dr->condition = err;
180     dr->which = Z_DefaultDiagFormat_v2Addinfo;
181     dr->u.v2Addinfo = odr_strdup (odr, addinfo ? addinfo : "");
182 }
183
184 Z_Records *Yaz_Z_ServerUtility::create_nonSurrogateDiagnostics (
185     ODR odr, int error, const char *addinfo)
186 {
187     int oid[OID_SIZE];
188     Z_Records *rec = (Z_Records *)
189         odr_malloc (odr, sizeof(*rec));
190     oident bib1;
191     int *err = (int *)
192         odr_malloc (odr, sizeof(*err));
193     Z_DiagRec *drec = (Z_DiagRec *)
194         odr_malloc (odr, sizeof(*drec));
195     Z_DefaultDiagFormat *dr = (Z_DefaultDiagFormat *)
196         odr_malloc (odr, sizeof(*dr));
197
198     bib1.proto = PROTO_Z3950;
199     bib1.oclass = CLASS_DIAGSET;
200     bib1.value = VAL_BIB1;
201
202     *err = error;
203     rec->which = Z_Records_NSD;
204     rec->u.nonSurrogateDiagnostic = dr;
205     dr->diagnosticSetId =
206         odr_oiddup (odr, oid_ent_to_oid(&bib1, oid));
207     dr->condition = err;
208     dr->which = Z_DefaultDiagFormat_v2Addinfo;
209     dr->u.v2Addinfo = odr_strdup (odr, addinfo ? addinfo : "");
210     return rec;
211 }