using yaz/log.h again
[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.20 2004-12-13 20:50:54 adam Exp $
6  */
7
8 #include <yaz/log.h>
9 #include <yaz++/z-server.h>
10
11 Yaz_Z_Server::Yaz_Z_Server(IYaz_PDU_Observable *the_PDU_Observable)
12     : Yaz_Z_Assoc(the_PDU_Observable)
13 {
14     m_facilities = 0;
15 }
16
17 Yaz_Z_Server::~Yaz_Z_Server()
18 {
19     facility_reset();
20 }
21
22 void Yaz_Z_Server::facility_reset ()
23 {
24     Yaz_Z_Server_Facility_Info *p = m_facilities;
25     while (p)
26     {
27         Yaz_Z_Server_Facility_Info *p_next = p->m_next;
28
29         delete [] p->m_name;
30         delete p;
31         p = p_next;
32     }
33     m_facilities = 0;
34 }
35
36 void Yaz_Z_Server::facility_add(IYaz_Server_Facility *facility,
37                                 const char *name)
38 {
39     Yaz_Z_Server_Facility_Info **p = &m_facilities;
40     while (*p)
41         p = &(*p)->m_next;
42
43     *p = new Yaz_Z_Server_Facility_Info;
44
45     (*p)->m_next = 0;
46     (*p)->m_name = new char [strlen(name)+1];
47     strcpy ((*p)->m_name, name);
48     (*p)->m_facility = facility;
49 }
50
51 void Yaz_Z_Server::recv_GDU (Z_GDU *apdu, int len)
52 {
53     if (apdu->which == Z_GDU_Z3950)
54         recv_Z_PDU(apdu->u.z3950, len);
55     else
56         delete this;
57 }
58
59 void Yaz_Z_Server::recv_Z_PDU (Z_APDU *apdu_request, int len)
60 {   
61     Yaz_Z_Server_Facility_Info *f = m_facilities;
62     
63     if (apdu_request->which == Z_APDU_initRequest)
64     {
65         Z_APDU *apdu_response = create_Z_PDU(Z_APDU_initResponse);
66
67         Z_InitRequest *req = apdu_request->u.initRequest;
68         Z_InitResponse *resp = apdu_response->u.initResponse;
69         
70         if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_1))
71         {
72             ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_1);
73         }
74         if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_2))
75         {
76             ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_2);
77         }
78         if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_3))
79         {
80             ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_3);
81         }
82         while (f)
83         {
84             f->m_facility->init(this, req, resp);
85             f = f->m_next;
86         }
87         transfer_referenceId(apdu_request, apdu_response);
88         send_Z_PDU(apdu_response, 0);
89     }
90     else
91     {
92         f = m_facilities;
93         int taken = 0;
94         while (f)
95         {
96             taken = f->m_facility->recv(this, apdu_request);
97             if (taken)
98                 break;
99             f = f->m_next;
100         }
101         if (!taken)
102         {
103             yaz_log (YLOG_WARN, "unhandled request = %d", apdu_request->which);
104             delete this;
105         }
106     }
107 }
108
109 /*
110  * database record.
111  */
112 void Yaz_Z_ServerUtility::create_databaseRecord (
113     ODR odr, Z_NamePlusRecord *rec, const char *dbname, int format,
114     const void *buf, int len)
115 {
116     rec->databaseName = dbname ? odr_strdup (odr, dbname) : 0;
117     rec->which = Z_NamePlusRecord_databaseRecord;
118     rec->u.databaseRecord = z_ext_record (odr, format,
119                                           (const char *) buf, len);
120 }
121
122 /*
123  * surrogate diagnostic.
124  */
125 void Yaz_Z_ServerUtility::create_surrogateDiagnostics(
126     ODR odr, Z_NamePlusRecord *rec, const char *dbname,
127     int error, char *const addinfo)
128 {
129     int *err = (int *)odr_malloc (odr, sizeof(*err));
130     Z_DiagRec *drec = (Z_DiagRec *)odr_malloc (odr, sizeof(*drec));
131     Z_DefaultDiagFormat *dr = (Z_DefaultDiagFormat *)
132         odr_malloc (odr, sizeof(*dr));
133     
134     yaz_log(YLOG_DEBUG, "SurrogateDiagnotic: %d -- %s", error, addinfo);
135     *err = error;
136     rec->databaseName = dbname ? odr_strdup (odr, dbname) : 0;
137     rec->which = Z_NamePlusRecord_surrogateDiagnostic;
138     rec->u.surrogateDiagnostic = drec;
139     drec->which = Z_DiagRec_defaultFormat;
140     drec->u.defaultFormat = dr;
141     dr->diagnosticSetId =
142         yaz_oidval_to_z3950oid (odr, CLASS_DIAGSET, VAL_BIB1);
143
144     dr->condition = err;
145     dr->which = Z_DefaultDiagFormat_v2Addinfo;
146     dr->u.v2Addinfo = odr_strdup (odr, addinfo ? addinfo : "");
147 }
148
149 Z_Records *Yaz_Z_ServerUtility::create_nonSurrogateDiagnostics (
150     ODR odr, int error, const char *addinfo)
151 {
152     Z_Records *rec = (Z_Records *)
153         odr_malloc (odr, sizeof(*rec));
154     int *err = (int *)
155         odr_malloc (odr, sizeof(*err));
156     Z_DiagRec *drec = (Z_DiagRec *)
157         odr_malloc (odr, sizeof(*drec));
158     Z_DefaultDiagFormat *dr = (Z_DefaultDiagFormat *)
159         odr_malloc (odr, sizeof(*dr));
160
161     *err = error;
162     rec->which = Z_Records_NSD;
163     rec->u.nonSurrogateDiagnostic = dr;
164     dr->diagnosticSetId =
165         yaz_oidval_to_z3950oid (odr, CLASS_DIAGSET, VAL_BIB1);
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 Yaz_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 =
188         yaz_oidval_to_z3950oid (odr, CLASS_DIAGSET, VAL_BIB1);
189     dr->condition = odr_intdup (odr, error);
190     dr->which = Z_DefaultDiagFormat_v2Addinfo;
191     dr->u.v2Addinfo = odr_strdup (odr, addinfo ? addinfo : "");
192 }