Using cs_get_host_args
[yazpp-moved-to-github.git] / src / yaz-ir-assoc.cpp
1 /* This file is part of the yazpp toolkit.
2  * Copyright (C) Index Data 
3  * See the file LICENSE for details.
4  */
5
6 #if HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9 #include <assert.h>
10
11 #include <yaz/log.h>
12 #include <yazpp/ir-assoc.h>
13 #include <yaz/oid_db.h>
14 #include <yaz/comstack.h>
15
16 using namespace yazpp_1;
17
18 IR_Assoc::IR_Assoc(IPDU_Observable *the_PDU_Observable)
19     : Z_Assoc(the_PDU_Observable)
20 {
21     m_num_databaseNames = 0;
22     m_databaseNames = 0;
23     m_preferredRecordSyntax = 0;
24     m_elementSetNames = 0;
25     m_lastReceived = 0;
26     m_host = 0;
27     m_proxy = 0;
28     m_cookie = 0;
29     m_log = YLOG_DEBUG;
30     const char *db = "Default";
31     set_databaseNames(1, &db);
32 }
33
34 IR_Assoc::~IR_Assoc()
35 {
36     xfree(m_preferredRecordSyntax);
37     if (m_elementSetNames)
38         delete [] m_elementSetNames->u.generic;
39     delete [] m_elementSetNames;
40     delete [] m_host;
41     delete [] m_proxy;
42     delete [] m_cookie;
43 }
44
45 void IR_Assoc::get_databaseNames (int *num, char ***list)
46 {
47     *num = m_num_databaseNames;
48     *list = m_databaseNames;
49 }
50
51 typedef char *charp;
52 void IR_Assoc::set_databaseNames (int num, const char **list)
53 {
54     int i;
55     yaz_log (m_log, "IR_Assoc::set_databaseNames num=%d", num);
56     for (i = 0; i<m_num_databaseNames; i++)
57         delete [] m_databaseNames[i];
58     delete [] m_databaseNames;
59     m_num_databaseNames = num;
60
61     m_databaseNames = new char *[num];
62     for (i = 0; i<m_num_databaseNames; i++)
63     {
64         m_databaseNames[i] = new char[strlen(list[i])+1];
65         strcpy(m_databaseNames[i], list[i]);
66     }
67 }
68
69 void IR_Assoc::set_databaseNames(const char *dblist, const char *sep)
70 {
71     const char **list = new const char* [strlen(dblist)];
72     char *dbtmp = new char[strlen(dblist)+1];
73     strcpy(dbtmp, dblist);
74     int num = 0;
75     int len = 0;
76     for (char *cp = dbtmp; ; cp++)
77         if (*cp && !strchr(sep, *cp))
78             len++;
79         else
80         {
81             if (len)
82             {
83                 list[num] = cp - len;
84                 num++;
85             }
86             if (!*cp)
87                 break;
88             *cp = '\0';
89             len = 0;
90         }
91     set_databaseNames (num, list);
92     delete [] dbtmp;
93     delete [] list;
94 }
95
96 void IR_Assoc::set_preferredRecordSyntax (const char *syntax)
97 {
98     xfree(m_preferredRecordSyntax);
99     m_preferredRecordSyntax = 0;
100     if (syntax && *syntax)
101         m_preferredRecordSyntax = xstrdup(syntax);
102 }
103
104 void IR_Assoc::get_preferredRecordSyntax (const char **dst)
105 {
106     if (m_preferredRecordSyntax)
107         *dst = m_preferredRecordSyntax;
108     else
109         *dst = "";
110 }
111
112 void IR_Assoc::set_elementSetName (const char *elementSetName)
113 {
114     if (m_elementSetNames)
115         delete [] m_elementSetNames->u.generic;
116     delete m_elementSetNames;
117     m_elementSetNames = 0;
118     if (elementSetName && *elementSetName)
119     {
120         m_elementSetNames = new Z_ElementSetNames;
121         m_elementSetNames->which = Z_ElementSetNames_generic;
122         m_elementSetNames->u.generic = new char[strlen(elementSetName)+1];
123         strcpy (m_elementSetNames->u.generic, elementSetName);
124     }
125 }
126
127 void IR_Assoc::get_elementSetName (Z_ElementSetNames **elementSetNames)
128 {
129     *elementSetNames = m_elementSetNames;
130 }
131
132 void IR_Assoc::get_elementSetName (const char **elementSetName)
133 {
134     if (!m_elementSetNames ||
135         m_elementSetNames->which != Z_ElementSetNames_generic)
136     {
137         *elementSetName = 0;
138         return;
139     }
140     *elementSetName = m_elementSetNames->u.generic;
141 }
142
143
144 void IR_Assoc::recv_GDU(Z_GDU *apdu, int len)
145 {
146     if (apdu->which == Z_GDU_Z3950)
147             recv_Z_PDU(apdu->u.z3950, len);
148 }
149
150 void IR_Assoc::recv_Z_PDU(Z_APDU *apdu, int len)
151 {
152     yaz_log (m_log, "recv_Z_PDU %d bytes", len);
153     m_lastReceived = apdu->which;
154     switch (apdu->which)
155     {
156     case Z_APDU_initResponse:
157         yaz_log (m_log, "recv InitResponse");
158         recv_initResponse(apdu->u.initResponse);
159         break;
160     case Z_APDU_initRequest:
161         yaz_log (m_log, "recv InitRequest");
162         recv_initRequest(apdu->u.initRequest);
163         break;
164     case Z_APDU_searchRequest:
165         yaz_log (m_log, "recv searchRequest");
166         recv_searchRequest(apdu->u.searchRequest);
167         break;
168     case Z_APDU_searchResponse:
169         yaz_log (m_log, "recv searchResponse");
170         recv_searchResponse(apdu->u.searchResponse);
171         break;
172     case Z_APDU_presentRequest:
173         yaz_log (m_log, "recv presentRequest");
174         recv_presentRequest(apdu->u.presentRequest);
175         break;
176     case Z_APDU_presentResponse:
177         yaz_log (m_log, "recv presentResponse");
178         recv_presentResponse(apdu->u.presentResponse);
179         break;
180     case Z_APDU_extendedServicesResponse:
181         yaz_log (m_log, "recv extendedServiceResponse");
182         recv_extendedServicesResponse(apdu->u.extendedServicesResponse);
183         break;
184     }
185 }
186
187 int IR_Assoc::send_searchRequest(Yaz_Z_Query *query,
188                                      char* pResultSetId,
189                                      char* pRefId)
190 {
191     Z_APDU *apdu = create_Z_PDU(Z_APDU_searchRequest);
192     Z_SearchRequest *req = apdu->u.searchRequest;
193
194     req->query = query->get_Z_Query();
195     if (!req->query)
196         return -1;
197     get_databaseNames (&req->num_databaseNames, &req->databaseNames);
198     const char *recordSyntax;
199     get_preferredRecordSyntax(&recordSyntax);
200     if (recordSyntax && *recordSyntax)
201     {
202         req->preferredRecordSyntax
203             = yaz_string_to_oid_odr(yaz_oid_std(), CLASS_RECSYN, recordSyntax,
204                                     odr_encode());
205     }
206     yaz_log (m_log, "send_searchRequest");
207     assert (req->otherInfo == 0);
208     if (m_cookie)
209     {
210         set_otherInformationString(&req->otherInfo, yaz_oid_userinfo_cookie,
211                                    1, m_cookie);
212         assert (req->otherInfo);
213     }
214
215     if ( pRefId )
216     {
217         req->referenceId = getRefID(pRefId);
218     }
219
220     if ( pResultSetId )
221     {
222         req->resultSetName = pResultSetId;
223     }
224
225     return send_Z_PDU(apdu, 0);
226 }
227
228 int IR_Assoc::send_presentRequest(Odr_int start,
229                                   Odr_int number,
230                                   char* pResultSetId,
231                                   char* pRefId)
232 {
233     Z_APDU *apdu = create_Z_PDU(Z_APDU_presentRequest);
234     Z_PresentRequest *req = apdu->u.presentRequest;
235
236     req->resultSetStartPoint = &start;
237     req->numberOfRecordsRequested = &number;
238
239     const char *recordSyntax;
240     get_preferredRecordSyntax (&recordSyntax);
241     if (recordSyntax && *recordSyntax)
242     {
243         req->preferredRecordSyntax =
244             yaz_string_to_oid_odr(yaz_oid_std(), CLASS_RECSYN, recordSyntax,
245                                   odr_encode());
246     }
247     Z_RecordComposition compo;
248     Z_ElementSetNames *elementSetNames;
249     get_elementSetName (&elementSetNames);
250     if (elementSetNames)
251     {
252         req->recordComposition = &compo;
253         compo.which = Z_RecordComp_simple;
254         compo.u.simple = elementSetNames;
255     }
256
257     if (m_cookie)
258         set_otherInformationString(&req->otherInfo, yaz_oid_userinfo_cookie,
259                                    1, m_cookie);
260
261     if ( pRefId )
262     {
263         req->referenceId = getRefID(pRefId);
264     }
265
266     if ( pResultSetId )
267     {
268         req->resultSetId = pResultSetId;
269     }
270
271     return send_Z_PDU(apdu, 0);
272 }
273
274 void IR_Assoc::set_proxy(const char *str)
275 {
276     delete [] m_proxy;
277     m_proxy = 0;
278     if (str)
279     {
280         m_proxy = new char[strlen(str)+1];
281         strcpy (m_proxy, str);
282     }
283 }
284
285 void IR_Assoc::set_cookie(const char *str)
286 {
287     delete [] m_cookie;
288     m_cookie = 0;
289     if (str)
290     {
291         m_cookie = new char[strlen(str)+1];
292         strcpy(m_cookie, str);
293     }
294 }
295
296 const char *IR_Assoc::get_cookie()
297 {
298     return m_cookie;
299 }
300
301 void IR_Assoc::client(const char *addr)
302 {
303     delete [] m_host;
304     m_host = new char[strlen(addr)+1];
305     strcpy(m_host, addr);
306     const char *dbpart = 0;
307     cs_get_host_args(m_host, &dbpart);
308     if (dbpart && *dbpart)
309         set_databaseNames (dbpart, "+ ");
310     Z_Assoc::client(m_proxy ? m_proxy : m_host);
311 }
312
313 const char *IR_Assoc::get_proxy()
314 {
315     return m_proxy;
316 }
317
318 const char *IR_Assoc::get_host()
319 {
320     return m_host;
321 }
322
323 void IR_Assoc::recv_searchRequest(Z_SearchRequest *searchRequest)
324 {
325     Z_APDU *apdu = create_Z_PDU(Z_APDU_searchResponse);
326     send_Z_PDU(apdu, 0);
327 }
328
329 void IR_Assoc::recv_presentRequest(Z_PresentRequest *presentRequest)
330 {
331     Z_APDU *apdu = create_Z_PDU(Z_APDU_presentResponse);
332     send_Z_PDU(apdu, 0);
333 }
334
335 void IR_Assoc::recv_initRequest(Z_InitRequest *initRequest)
336 {
337     Z_APDU *apdu = create_Z_PDU(Z_APDU_initResponse);
338     send_Z_PDU(apdu, 0);
339 }
340
341 void IR_Assoc::recv_searchResponse (Z_SearchResponse *searchResponse)
342 {
343 }
344
345 void IR_Assoc::recv_presentResponse (Z_PresentResponse *presentResponse)
346 {
347 }
348
349 void IR_Assoc::recv_initResponse(Z_InitResponse *initResponse)
350 {
351 }
352
353 void IR_Assoc::recv_extendedServicesResponse(Z_ExtendedServicesResponse *ExtendedServicesResponse)
354 {
355 }
356
357 int IR_Assoc::get_lastReceived()
358 {
359     return m_lastReceived;
360 }
361
362 void IR_Assoc::set_lastReceived(int lastReceived)
363 {
364     m_lastReceived = lastReceived;
365 }
366
367 int IR_Assoc::send_initRequest(char* pRefId)
368 {
369     Z_APDU *apdu = create_Z_PDU(Z_APDU_initRequest);
370     Z_InitRequest *req = apdu->u.initRequest;
371
372     ODR_MASK_SET(req->options, Z_Options_search);
373     ODR_MASK_SET(req->options, Z_Options_present);
374     ODR_MASK_SET(req->options, Z_Options_namedResultSets);
375     ODR_MASK_SET(req->options, Z_Options_triggerResourceCtrl);
376     ODR_MASK_SET(req->options, Z_Options_scan);
377     ODR_MASK_SET(req->options, Z_Options_sort);
378     ODR_MASK_SET(req->options, Z_Options_extendedServices);
379     ODR_MASK_SET(req->options, Z_Options_delSet);
380
381     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1);
382     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2);
383     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3);
384
385     if ( pRefId )
386     {
387         req->referenceId = getRefID(pRefId);
388     }
389
390     if (m_proxy && m_host)
391         set_otherInformationString(&req->otherInfo, yaz_oid_userinfo_proxy,
392                                    1, m_host);
393     if (m_cookie)
394         set_otherInformationString(&req->otherInfo, yaz_oid_userinfo_cookie,
395                                    1, m_cookie);
396     return send_Z_PDU(apdu, 0);
397 }
398
399 int IR_Assoc::send_deleteResultSetRequest(char* pResultSetId, char* pRefId)
400 {
401     char* ResultSetIds[1];
402
403     Z_APDU *apdu = create_Z_PDU(Z_APDU_deleteResultSetRequest);
404     Z_DeleteResultSetRequest *req = apdu->u.deleteResultSetRequest;
405
406     if ( pResultSetId )
407     {
408         *req->deleteFunction = Z_DeleteResultSetRequest_list;
409         req->num_resultSetList = 1;
410         ResultSetIds[0] = pResultSetId;
411         req->resultSetList = ResultSetIds;
412     }
413     else
414     {
415         *req->deleteFunction = Z_DeleteResultSetRequest_all;
416     }
417
418     if ( pRefId )
419     {
420         req->referenceId = getRefID(pRefId);
421     }
422
423     if (m_proxy && m_host)
424         set_otherInformationString(&req->otherInfo, yaz_oid_userinfo_proxy,
425                                    1, m_host);
426     if (m_cookie)
427         set_otherInformationString(&req->otherInfo, yaz_oid_userinfo_cookie,
428                                    1, m_cookie);
429
430     return send_Z_PDU(apdu, 0);
431 }
432
433
434 /*
435  * Local variables:
436  * c-basic-offset: 4
437  * c-file-style: "Stroustrup"
438  * indent-tabs-mode: nil
439  * End:
440  * vim: shiftwidth=4 tabstop=8 expandtab
441  */
442