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