Release 1.6.4
[yazpp-moved-to-github.git] / src / yaz-z-server.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 <yaz/log.h>
10 #include <yazpp/z-server.h>
11 #include <yaz/oid_db.h>
12
13 using namespace yazpp_1;
14
15 Z_Server::Z_Server(IPDU_Observable *the_PDU_Observable)
16     : Z_Assoc(the_PDU_Observable)
17 {
18     m_facilities = 0;
19 }
20
21 Z_Server::~Z_Server()
22 {
23     facility_reset();
24 }
25
26 void Z_Server::facility_reset ()
27 {
28     Z_Server_Facility_Info *p = m_facilities;
29     while (p)
30     {
31         Z_Server_Facility_Info *p_next = p->m_next;
32
33         delete [] p->m_name;
34         delete p;
35         p = p_next;
36     }
37     m_facilities = 0;
38 }
39
40 void Z_Server::facility_add(IServer_Facility *facility,
41                             const char *name)
42 {
43     Z_Server_Facility_Info **p = &m_facilities;
44     while (*p)
45         p = &(*p)->m_next;
46
47     *p = new Z_Server_Facility_Info;
48
49     (*p)->m_next = 0;
50     (*p)->m_name = new char [strlen(name)+1];
51     strcpy ((*p)->m_name, name);
52     (*p)->m_facility = facility;
53 }
54
55 void Z_Server::recv_GDU (Z_GDU *apdu, int len)
56 {
57     if (apdu->which == Z_GDU_Z3950)
58         recv_Z_PDU(apdu->u.z3950, len);
59     else
60         delete this;
61 }
62
63 void Z_Server::recv_Z_PDU (Z_APDU *apdu_request, int len)
64 {
65     Z_Server_Facility_Info *f = m_facilities;
66
67     if (apdu_request->which == Z_APDU_initRequest)
68     {
69         Z_APDU *apdu_response = create_Z_PDU(Z_APDU_initResponse);
70
71         Z_InitRequest *req = apdu_request->u.initRequest;
72         Z_InitResponse *resp = apdu_response->u.initResponse;
73
74         if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_1))
75         {
76             ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_1);
77         }
78         if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_2))
79         {
80             ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_2);
81         }
82         if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_3))
83         {
84             ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_3);
85         }
86         while (f)
87         {
88             f->m_facility->init(this, req, resp);
89             f = f->m_next;
90         }
91         transfer_referenceId(apdu_request, apdu_response);
92         send_Z_PDU(apdu_response, 0);
93     }
94     else
95     {
96         f = m_facilities;
97         int taken = 0;
98         while (f)
99         {
100             taken = f->m_facility->recv(this, apdu_request);
101             if (taken)
102                 break;
103             f = f->m_next;
104         }
105         if (!taken)
106         {
107             yaz_log (YLOG_WARN, "unhandled request = %d", apdu_request->which);
108             delete this;
109         }
110     }
111 }
112
113 /*
114  * database record.
115  */
116 void Z_ServerUtility::create_databaseRecord (
117     ODR odr, Z_NamePlusRecord *rec, const char *dbname, const Odr_oid *format,
118     const void *buf, int len)
119 {
120     Odr_oid *oid = odr_oiddup(odr, format);
121     rec->databaseName = dbname ? odr_strdup (odr, dbname) : 0;
122     rec->which = Z_NamePlusRecord_databaseRecord;
123     rec->u.databaseRecord = z_ext_record_oid(odr, oid,
124                                              (const char *) buf, len);
125 }
126
127 /*
128  * surrogate diagnostic.
129  */
130 void Z_ServerUtility::create_surrogateDiagnostics(
131     ODR odr, Z_NamePlusRecord *rec, const char *dbname,
132     int error, char *const addinfo)
133 {
134     Odr_int *err = (Odr_int *)odr_malloc (odr, sizeof(*err));
135     Z_DiagRec *drec = (Z_DiagRec *)odr_malloc (odr, sizeof(*drec));
136     Z_DefaultDiagFormat *dr = (Z_DefaultDiagFormat *)
137         odr_malloc (odr, sizeof(*dr));
138
139     yaz_log(YLOG_DEBUG, "SurrogateDiagnotic: %d -- %s", error, addinfo);
140     *err = error;
141     rec->databaseName = dbname ? odr_strdup (odr, dbname) : 0;
142     rec->which = Z_NamePlusRecord_surrogateDiagnostic;
143     rec->u.surrogateDiagnostic = drec;
144     drec->which = Z_DiagRec_defaultFormat;
145     drec->u.defaultFormat = dr;
146     dr->diagnosticSetId = odr_oiddup(odr, yaz_oid_diagset_bib_1);
147
148     dr->condition = err;
149     dr->which = Z_DefaultDiagFormat_v2Addinfo;
150     dr->u.v2Addinfo = odr_strdup (odr, addinfo ? addinfo : "");
151 }
152
153 Z_Records *Z_ServerUtility::create_nonSurrogateDiagnostics (
154     ODR odr, int error, const char *addinfo)
155 {
156     Z_Records *rec = (Z_Records *)
157         odr_malloc (odr, sizeof(*rec));
158     Odr_int *err = (Odr_int *)
159         odr_malloc (odr, sizeof(*err));
160     Z_DiagRec *drec = (Z_DiagRec *)
161         odr_malloc (odr, sizeof(*drec));
162     Z_DefaultDiagFormat *dr = (Z_DefaultDiagFormat *)
163         odr_malloc (odr, sizeof(*dr));
164
165     *err = error;
166     rec->which = Z_Records_NSD;
167     rec->u.nonSurrogateDiagnostic = dr;
168     dr->diagnosticSetId = odr_oiddup(odr, yaz_oid_diagset_bib_1);
169
170     dr->condition = err;
171     dr->which = Z_DefaultDiagFormat_v2Addinfo;
172     dr->u.v2Addinfo = odr_strdup (odr, addinfo ? addinfo : "");
173     return rec;
174 }
175
176 void Z_ServerUtility::create_diagnostics (
177     ODR odr, int error, const char *addinfo,
178     Z_DiagRec ***dreca, int *num)
179 {
180     Z_DiagRec *drec = (Z_DiagRec *) odr_malloc (odr, sizeof(*drec));
181     Z_DefaultDiagFormat *dr = (Z_DefaultDiagFormat *)
182         odr_malloc (odr, sizeof(*dr));
183
184     *num = 1;
185     *dreca = (Z_DiagRec **) odr_malloc (odr, sizeof(*dreca));
186     (*dreca)[0] = drec;
187
188     drec->which = Z_DiagRec_defaultFormat;
189     drec->u.defaultFormat = dr;
190     dr->diagnosticSetId = odr_oiddup(odr, yaz_oid_diagset_bib_1);
191     dr->condition = odr_intdup (odr, error);
192     dr->which = Z_DefaultDiagFormat_v2Addinfo;
193     dr->u.v2Addinfo = odr_strdup (odr, addinfo ? addinfo : "");
194 }
195 /*
196  * Local variables:
197  * c-basic-offset: 4
198  * c-file-style: "Stroustrup"
199  * indent-tabs-mode: nil
200  * End:
201  * vim: shiftwidth=4 tabstop=8 expandtab
202  */
203