Added include stdlib.h
[yazpp-moved-to-github.git] / src / yaz-my-server.cpp
1 /*
2  * Copyright (c) 1998-2001, Index Data.
3  * See the file LICENSE for details.
4  * 
5  * $Id: yaz-my-server.cpp,v 1.15 2005-01-17 09:55:58 adam Exp $
6  */
7
8 #include <stdlib.h>
9 #include <yaz/log.h>
10 #include <yaz/options.h>
11 #include <yaz++/z-server.h>
12 #include <yaz++/pdu-assoc.h>
13 #include <yaz++/socket-manager.h>
14
15 class MyILL : public Yaz_Facility_ILL {
16 public:
17     void ill_service (Z_ExtendedServicesRequest *req,
18                       Z_ItemOrder *io,
19                       Z_ExtendedServicesResponse *res);
20 };
21
22 class MyUpdate : public Yaz_Facility_Update {
23 public:
24     void update_service (Z_ExtendedServicesRequest *req,
25                          Z_IUUpdate *io,
26                          Z_ExtendedServicesResponse *res);
27     void update_service0 (Z_ExtendedServicesRequest *req,
28                          Z_IU0Update *io,
29                          Z_ExtendedServicesResponse *res);
30 };
31
32
33 class MyRetrieval : public Yaz_Facility_Retrieval, Yaz_USMARC {
34 public:
35     int sr_init (Z_InitRequest *initRequest,
36                  Z_InitResponse *initResponse);
37     void sr_search (Z_SearchRequest *searchRequest,
38                         Z_SearchResponse *searchResponse);
39     void sr_present (Z_PresentRequest *presentRequest,
40                          Z_PresentResponse *presentResponse);
41     void sr_record (const char *resultSetName,
42                     int position,
43                     int *format,
44                     Z_RecordComposition *comp,
45                     Z_NamePlusRecord *namePlusRecord,
46                     Z_Records *records);
47 };
48
49 class MyServer : public Yaz_Z_Server {
50 public:
51     ~MyServer();
52     MyServer(IYaz_PDU_Observable *the_PDU_Observable);
53     IYaz_PDU_Observer* sessionNotify(IYaz_PDU_Observable *the_PDU_Observable,
54                                      int fd);
55     void failNotify();
56     void timeoutNotify();
57     void connectNotify();
58
59 private:
60     MyRetrieval m_retrieval;
61     MyILL       m_ill;
62     MyUpdate    m_update;
63     int m_no;
64 };
65
66 void MyILL::ill_service (Z_ExtendedServicesRequest *req,
67                          Z_ItemOrder *io,
68                          Z_ExtendedServicesResponse *res)
69 {
70     yaz_log (YLOG_LOG, "MyServer::ill_service");
71 }
72
73 void MyUpdate::update_service (Z_ExtendedServicesRequest *req,
74                            Z_IUUpdate *io,
75                            Z_ExtendedServicesResponse *res)
76 {
77     yaz_log (YLOG_LOG, "MyServer::update_service (v1.1)");
78 }
79
80 void MyUpdate::update_service0 (Z_ExtendedServicesRequest *req,
81                            Z_IU0Update *io,
82                                 Z_ExtendedServicesResponse *res)
83 {
84     yaz_log (YLOG_LOG, "MyServer::update_service (v1.0)");
85 }
86
87 int MyRetrieval::sr_init (Z_InitRequest *initRequest,
88                        Z_InitResponse *initResponse)
89 {
90     yaz_log (YLOG_LOG, "MyServer::sr_init");
91     return 1;
92 }
93
94 void MyRetrieval::sr_search (Z_SearchRequest *searchRequest,
95                              Z_SearchResponse *searchResponse)
96 {
97     yaz_log (YLOG_LOG, "MyServer::recv_Z_search");
98     if (searchRequest->query->which == Z_Query_type_1)
99     {
100         Z_RPNStructure *s = searchRequest->query->u.type_1->RPNStructure;
101         if (s->which == Z_RPNStructure_simple &&
102             s->u.simple->which == Z_Operand_APT &&
103             s->u.simple->u.attributesPlusTerm->term->which == Z_Term_general)
104         {
105             Odr_oct *term = s->u.simple->u.attributesPlusTerm->term->u.general;
106             char *str = (char *) odr_malloc (odr_encode(), term->len+1);
107             if (term->len)
108                 memcpy (str, term->buf, term->len);
109             str[term->len] = '\0';
110             *searchResponse->resultCount = atoi(str);
111         }
112     }
113 }
114
115 void MyRetrieval::sr_present (Z_PresentRequest *presentRequest,
116                                Z_PresentResponse *presentResponse)
117 {
118     yaz_log (YLOG_LOG, "MyServer::recv_Z_present");
119 }
120
121 void MyRetrieval::sr_record (const char *resultSetName,
122                              int position,
123                              int *format,
124                              Z_RecordComposition *comp,
125                              Z_NamePlusRecord *namePlusRecord,
126                              Z_Records *records)
127 {
128     yaz_log (YLOG_LOG, "MyServer::recv_Z_record");
129     const char *rec = get_record(position);
130     create_databaseRecord (odr_encode(), namePlusRecord, 0, VAL_USMARC, rec,
131                            strlen(rec));
132 }
133
134 MyServer::~MyServer()
135 {
136 }
137
138 IYaz_PDU_Observer *MyServer::sessionNotify(
139     IYaz_PDU_Observable *the_PDU_Observable, int fd)
140 {
141     MyServer *new_server;
142     m_no++;
143     new_server = new MyServer(the_PDU_Observable);
144     new_server->timeout(900);
145     new_server->facility_add(&new_server->m_retrieval, "my sr");
146     new_server->facility_add(&new_server->m_ill, "my ill");
147     new_server->facility_add(&new_server->m_update, "my update");
148     new_server->set_APDU_log(get_APDU_log());
149
150     return new_server;
151 }
152
153 MyServer::MyServer(IYaz_PDU_Observable *the_PDU_Observable) :
154     Yaz_Z_Server (the_PDU_Observable)
155 {
156     m_no = 0;
157 }
158
159 void MyServer::timeoutNotify()
160 {
161     yaz_log (YLOG_LOG, "connection timed out");
162     delete this;
163 }
164
165 void MyServer::failNotify()
166 {
167     yaz_log (YLOG_LOG, "connection closed by client");
168     delete this;
169 }
170
171 void MyServer::connectNotify()
172 {
173 }
174
175 void usage(const char *prog)
176 {
177     fprintf (stderr, "%s: [-a log] [-v level] [-T] @:port\n", prog);
178     exit (1);
179 }
180
181 int main(int argc, char **argv)
182 {
183     int thread_flag = 0;
184     char *arg;
185     char *prog = *argv;
186     const char *addr = "tcp:@:9999";
187     char *apdu_log = 0;
188     
189     Yaz_SocketManager mySocketManager;
190     
191     Yaz_PDU_Assoc *my_PDU_Assoc = 0;
192     
193     MyServer *z = 0;
194     int ret;
195     
196     while ((ret = options("a:v:T", argv, argc, &arg)) != -2)
197     {
198         switch (ret)
199         {
200         case 0:
201             addr = xstrdup(arg);
202             break;
203         case 'a':
204             apdu_log = xstrdup(arg);
205             break;
206         case 'v':
207             yaz_log_init_level (yaz_log_mask_str(arg));
208             break;
209         case 'T':
210             thread_flag = 1;
211             break;
212         default:
213             usage(prog);
214             return 1;
215         }
216     }
217 #if YAZ_POSIX_THREADS
218     if (thread_flag)
219         my_PDU_Assoc = new Yaz_PDU_AssocThread(&mySocketManager);
220     else
221         my_PDU_Assoc = new Yaz_PDU_Assoc(&mySocketManager);
222 #else
223     my_PDU_Assoc = new Yaz_PDU_Assoc(&mySocketManager);
224 #endif
225     
226     z = new MyServer(my_PDU_Assoc);
227     z->server(addr);
228     if (apdu_log)
229     {
230         yaz_log (YLOG_LOG, "set_APDU_log %s", apdu_log);
231         z->set_APDU_log(apdu_log);
232     }
233
234     while (mySocketManager.processEvent() > 0)
235         ;
236     delete z;
237     return 0;
238 }