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