Work on proxy.
[yazpp-moved-to-github.git] / src / yaz-z-assoc.cpp
1 /*
2  * Copyright (c) 1998-1999, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  * 
6  * $Log: yaz-z-assoc.cpp,v $
7  * Revision 1.5  1999-11-10 10:02:34  adam
8  * Work on proxy.
9  *
10  * Revision 1.4  1999/09/13 12:53:44  adam
11  * Proxy removes OtherInfo Proxy Address and Session ID. Other
12  * Otherinfo remains untouched.
13  *
14  * Revision 1.3  1999/04/21 12:09:01  adam
15  * Many improvements. Modified to proxy server to work with "sessions"
16  * based on cookies.
17  *
18  * Revision 1.2  1999/04/20 10:30:05  adam
19  * Implemented various stuff for client and proxy. Updated calls
20  * to ODR to reflect new name parameter.
21  *
22  * Revision 1.1  1999/04/09 11:46:57  adam
23  * Added object Yaz_Z_Assoc. Much more functional client.
24  *
25  */
26
27 #include <assert.h>
28
29 #include <log.h>
30 #include <yaz-z-assoc.h>
31 #include <otherinfo.h>
32
33 int Yaz_Z_Assoc::yaz_init_func()
34 {
35     logf (LOG_LOG, "nmem_init");
36     nmem_init();
37     logf (LOG_LOG, "done");
38     return 1;
39 }
40
41 int Yaz_Z_Assoc::yaz_init_flag = Yaz_Z_Assoc::yaz_init_func();
42
43 Yaz_Z_Assoc::Yaz_Z_Assoc(IYaz_PDU_Observable *the_PDU_Observable)
44 {
45     m_PDU_Observable = the_PDU_Observable;
46     m_odr_in = odr_createmem (ODR_DECODE);
47     m_odr_out = odr_createmem (ODR_ENCODE);
48     m_odr_print = odr_createmem (ODR_PRINT);
49 }
50
51 Yaz_Z_Assoc::~Yaz_Z_Assoc()
52 {
53     m_PDU_Observable->destroy();
54     delete m_PDU_Observable;
55     odr_destroy (m_odr_print);
56     odr_destroy (m_odr_out);
57     odr_destroy (m_odr_in);
58 }
59
60 void Yaz_Z_Assoc::recv_PDU(const char *buf, int len)
61 {
62     logf (LOG_LOG, "recv_PDU len=%d", len);
63     Z_APDU *apdu = decode_Z_PDU (buf, len);
64     if (apdu)
65     {
66         recv_Z_PDU (apdu);
67     }
68 }
69
70 Z_APDU *Yaz_Z_Assoc::create_Z_PDU(int type)
71 {
72     Z_APDU *apdu = zget_APDU(m_odr_out, type);
73     if (apdu->which == Z_APDU_initRequest)
74     {
75         Z_InitRequest * p = apdu->u.initRequest;
76         char *newName = (char*) odr_malloc(m_odr_out, 50);
77         strcpy (newName, p->implementationName);
78         strcat (newName, " YAZ++");
79         p->implementationName = newName;
80     }
81     return apdu;
82 }
83
84 int Yaz_Z_Assoc::send_Z_PDU(Z_APDU *apdu)
85 {
86     char *buf;
87     int len;
88     logf (LOG_LOG, "Yaz_Z_Assoc:send_Z_PDU");
89     if (encode_Z_PDU(apdu, &buf, &len) > 0)
90         return m_PDU_Observable->send_PDU(buf, len);
91     return -1;
92 }
93
94 Z_APDU *Yaz_Z_Assoc::decode_Z_PDU(const char *buf, int len)
95 {
96     Z_APDU *apdu;
97
98     odr_reset (m_odr_in);
99     odr_setbuf (m_odr_in, (char*) buf, len, 0);
100
101     if (!z_APDU(m_odr_in, &apdu, 0, 0))
102     {
103         logf(LOG_LOG, "ODR error on incoming PDU: %s [near byte %d] ",
104              odr_errmsg(odr_geterror(m_odr_in)),
105              odr_offset(m_odr_in));
106         logf(LOG_LOG, "PDU dump:");
107         odr_dumpBER(log_file(), buf, len);
108         return 0;
109     }
110     else
111     {
112         z_APDU(m_odr_print, &apdu, 0, "decode");
113         return apdu;
114     }
115 }
116
117 int Yaz_Z_Assoc::encode_Z_PDU(Z_APDU *apdu, char **buf, int *len)
118 {
119     if (!z_APDU(m_odr_out, &apdu, 0, 0))
120     {
121         logf (LOG_LOG, "yaz_Z_Assoc::encode_Z_PDU failed");
122         return -1;
123     }
124     z_APDU(m_odr_print, &apdu, 0, "encode");
125     *buf = odr_getbuf (m_odr_out, len, 0);
126     odr_reset (m_odr_out);
127     return *len;
128 }
129
130 void Yaz_Z_Assoc::connectNotify()
131 {
132     logf (LOG_LOG, "connectNotify");
133 }
134
135 void Yaz_Z_Assoc::failNotify()
136 {
137     logf (LOG_LOG, "failNotify");
138 }
139
140 void Yaz_Z_Assoc::timeoutNotify()
141 {
142     logf (LOG_LOG, "timeoutNotify");
143 }
144
145 void Yaz_Z_Assoc::client(const char *addr)
146 {
147     m_PDU_Observable->connect (this, addr);
148 }
149
150 void Yaz_Z_Assoc::close()
151 {
152     m_PDU_Observable->close ();
153 }
154
155 void Yaz_Z_Assoc::server(const char *addr)
156 {
157     m_PDU_Observable->listen (this, addr);
158 }
159
160 ODR Yaz_Z_Assoc::odr_encode()
161 {
162     return m_odr_out;
163 }
164
165 ODR Yaz_Z_Assoc::odr_decode()
166 {
167     return m_odr_in;
168 }
169 ODR Yaz_Z_Assoc::odr_print()
170 {
171     return m_odr_print;
172 }
173
174 void Yaz_Z_Assoc::timeout(int timeout)
175 {
176     m_PDU_Observable->idleTime(timeout);
177 }
178
179 void Yaz_Z_Assoc::get_otherInfoAPDU(Z_APDU *apdu, Z_OtherInformation ***oip)
180 {
181     switch (apdu->which)
182     {
183     case Z_APDU_initRequest:
184         *oip = &apdu->u.initRequest->otherInfo;
185         break;
186     case Z_APDU_searchRequest:
187         *oip = &apdu->u.searchRequest->otherInfo;
188         break;
189     case Z_APDU_presentRequest:
190         *oip = &apdu->u.presentRequest->otherInfo;
191         break;
192     case Z_APDU_sortRequest:
193         *oip = &apdu->u.sortRequest->otherInfo;
194         break;
195     case Z_APDU_scanRequest:
196         *oip = &apdu->u.scanRequest->otherInfo;
197         break;
198     case Z_APDU_initResponse:
199         *oip = &apdu->u.initResponse->otherInfo;
200         break;
201     case Z_APDU_searchResponse:
202         *oip = &apdu->u.searchResponse->otherInfo;
203         break;
204     case Z_APDU_presentResponse:
205         *oip = &apdu->u.presentResponse->otherInfo;
206         break;
207     case Z_APDU_sortResponse:
208         *oip = &apdu->u.sortResponse->otherInfo;
209         break;
210     case Z_APDU_scanResponse:
211         *oip = &apdu->u.scanResponse->otherInfo;
212         break;
213     default:
214         *oip = 0;
215         break;
216     }
217 }
218
219 void Yaz_Z_Assoc::set_otherInformationString (
220     Z_APDU *apdu,
221     int oidval, int categoryValue,
222     const char *str)
223 {
224     Z_OtherInformation **otherInformation;
225     get_otherInfoAPDU(apdu, &otherInformation);
226     if (!otherInformation)
227         return;
228     set_otherInformationString(otherInformation, oidval, categoryValue, str);
229 }
230
231 void Yaz_Z_Assoc::set_otherInformationString (
232     Z_OtherInformation **otherInformation,
233     int oidval, int categoryValue,
234     const char *str)
235 {
236     int oid[OID_SIZE];
237     struct oident ent;
238     ent.proto = PROTO_Z3950;
239     ent.oclass = CLASS_USERINFO;
240     ent.value = (oid_value) oidval;
241     if (!oid_ent_to_oid (&ent, oid))
242         return ;
243     set_otherInformationString(otherInformation, oid, categoryValue, str);
244 }
245
246 void Yaz_Z_Assoc::set_otherInformationString (
247     Z_OtherInformation **otherInformation,
248     int *oid, int categoryValue, const char *str)
249 {
250     Z_OtherInformationUnit *oi =
251         update_otherInformation(otherInformation, 1, oid, categoryValue, 0);
252     if (!oi)
253         return;
254     oi->information.characterInfo = odr_strdup (odr_encode(), str);
255 }
256
257 Z_OtherInformationUnit *Yaz_Z_Assoc::update_otherInformation (
258     Z_OtherInformation **otherInformationP, int createFlag,
259     int *oid, int categoryValue, int deleteFlag)
260 {
261     return yaz_oi_update (otherInformationP,
262                           (createFlag ? odr_encode() : 0),
263                           oid, categoryValue, deleteFlag);
264 }
265