Removed prefix Yaz_ from several class - and interface names now
[yazpp-moved-to-github.git] / src / yaz-z-server.cpp
1 /*
2  * Copyright (c) 2000-2004, Index Data.
3  * See the file LICENSE for details.
4  * 
5  * $Id: yaz-z-server.cpp,v 1.22 2005-06-08 13:28:06 adam Exp $
6  */
7
8 #include <yaz/log.h>
9 #include <yaz++/z-server.h>
10
11 using namespace yazpp_1;
12
13 Z_Server::Z_Server(IPDU_Observable *the_PDU_Observable)
14     : Z_Assoc(the_PDU_Observable)
15 {
16     m_facilities = 0;
17 }
18
19 Z_Server::~Z_Server()
20 {
21     facility_reset();
22 }
23
24 void Z_Server::facility_reset ()
25 {
26     Z_Server_Facility_Info *p = m_facilities;
27     while (p)
28     {
29         Z_Server_Facility_Info *p_next = p->m_next;
30
31         delete [] p->m_name;
32         delete p;
33         p = p_next;
34     }
35     m_facilities = 0;
36 }
37
38 void Z_Server::facility_add(IServer_Facility *facility,
39                             const char *name)
40 {
41     Z_Server_Facility_Info **p = &m_facilities;
42     while (*p)
43         p = &(*p)->m_next;
44
45     *p = new Z_Server_Facility_Info;
46
47     (*p)->m_next = 0;
48     (*p)->m_name = new char [strlen(name)+1];
49     strcpy ((*p)->m_name, name);
50     (*p)->m_facility = facility;
51 }
52
53 void Z_Server::recv_GDU (Z_GDU *apdu, int len)
54 {
55     if (apdu->which == Z_GDU_Z3950)
56         recv_Z_PDU(apdu->u.z3950, len);
57     else
58         delete this;
59 }
60
61 void Z_Server::recv_Z_PDU (Z_APDU *apdu_request, int len)
62 {   
63     Z_Server_Facility_Info *f = m_facilities;
64     
65     if (apdu_request->which == Z_APDU_initRequest)
66     {
67         Z_APDU *apdu_response = create_Z_PDU(Z_APDU_initResponse);
68
69         Z_InitRequest *req = apdu_request->u.initRequest;
70         Z_InitResponse *resp = apdu_response->u.initResponse;
71         
72         if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_1))
73         {
74             ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_1);
75         }
76         if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_2))
77         {
78             ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_2);
79         }
80         if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_3))
81         {
82             ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_3);
83         }
84         while (f)
85         {
86             f->m_facility->init(this, req, resp);
87             f = f->m_next;
88         }
89         transfer_referenceId(apdu_request, apdu_response);
90         send_Z_PDU(apdu_response, 0);
91     }
92     else
93     {
94         f = m_facilities;
95         int taken = 0;
96         while (f)
97         {
98             taken = f->m_facility->recv(this, apdu_request);
99             if (taken)
100                 break;
101             f = f->m_next;
102         }
103         if (!taken)
104         {
105             yaz_log (YLOG_WARN, "unhandled request = %d", apdu_request->which);
106             delete this;
107         }
108     }
109 }
110
111 /*
112  * database record.
113  */
114 void Z_ServerUtility::create_databaseRecord (
115     ODR odr, Z_NamePlusRecord *rec, const char *dbname, int format,
116     const void *buf, int len)
117 {
118     rec->databaseName = dbname ? odr_strdup (odr, dbname) : 0;
119     rec->which = Z_NamePlusRecord_databaseRecord;
120     rec->u.databaseRecord = z_ext_record (odr, format,
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 =
144         yaz_oidval_to_z3950oid (odr, CLASS_DIAGSET, VAL_BIB1);
145
146     dr->condition = err;
147     dr->which = Z_DefaultDiagFormat_v2Addinfo;
148     dr->u.v2Addinfo = odr_strdup (odr, addinfo ? addinfo : "");
149 }
150
151 Z_Records *Z_ServerUtility::create_nonSurrogateDiagnostics (
152     ODR odr, int error, const char *addinfo)
153 {
154     Z_Records *rec = (Z_Records *)
155         odr_malloc (odr, sizeof(*rec));
156     int *err = (int *)
157         odr_malloc (odr, sizeof(*err));
158     Z_DiagRec *drec = (Z_DiagRec *)
159         odr_malloc (odr, sizeof(*drec));
160     Z_DefaultDiagFormat *dr = (Z_DefaultDiagFormat *)
161         odr_malloc (odr, sizeof(*dr));
162
163     *err = error;
164     rec->which = Z_Records_NSD;
165     rec->u.nonSurrogateDiagnostic = dr;
166     dr->diagnosticSetId =
167         yaz_oidval_to_z3950oid (odr, CLASS_DIAGSET, VAL_BIB1);
168
169     dr->condition = err;
170     dr->which = Z_DefaultDiagFormat_v2Addinfo;
171     dr->u.v2Addinfo = odr_strdup (odr, addinfo ? addinfo : "");
172     return rec;
173 }
174
175 void Z_ServerUtility::create_diagnostics (
176     ODR odr, int error, const char *addinfo,
177     Z_DiagRec ***dreca, int *num)
178 {
179     Z_DiagRec *drec = (Z_DiagRec *) odr_malloc (odr, sizeof(*drec));
180     Z_DefaultDiagFormat *dr = (Z_DefaultDiagFormat *)
181         odr_malloc (odr, sizeof(*dr));
182     
183     *num = 1;
184     *dreca = (Z_DiagRec **) odr_malloc (odr, sizeof(*dreca));
185     (*dreca)[0] = drec;
186         
187     drec->which = Z_DiagRec_defaultFormat;
188     drec->u.defaultFormat = dr;
189     dr->diagnosticSetId =
190         yaz_oidval_to_z3950oid (odr, CLASS_DIAGSET, VAL_BIB1);
191     dr->condition = odr_intdup (odr, error);
192     dr->which = Z_DefaultDiagFormat_v2Addinfo;
193     dr->u.v2Addinfo = odr_strdup (odr, addinfo ? addinfo : "");
194 }