Minor change to prevent warning.
[yaz-moved-to-github.git] / ztest / ztest.c
1 /*
2  * Copyright (c) 1995-1998, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * NT Service interface by
7  *    Chas Woodfield, Fretwell Downing Datasystems.
8  *
9  * $Log: ztest.c,v $
10  * Revision 1.19  1998-10-20 15:16:22  adam
11  * Minor change to prevent warning.
12  *
13  * Revision 1.18  1998/10/20 15:13:45  adam
14  * Minor fix regarding output for Item Order.
15  *
16  * Revision 1.17  1998/10/18 22:33:35  quinn
17  * Added diagnostic dump of Item Order Eservice.
18  *
19  * Revision 1.16  1998/10/15 08:26:23  adam
20  * Added type cast to make C++ happy.
21  *
22  * Revision 1.15  1998/10/13 20:05:57  adam
23  * Minor change.
24  *
25  * Revision 1.14  1998/10/13 16:12:25  adam
26  * Added support for Surrogate Diagnostics for Scan Term entries.
27  *
28  * Revision 1.13  1998/08/19 16:10:09  adam
29  * Changed som member names of DeleteResultSetRequest/Response.
30  *
31  * Revision 1.12  1998/07/20 12:38:44  adam
32  * Implemented delete result set service to server API.
33  *
34  * Revision 1.11  1998/06/09 13:55:08  adam
35  * Minor changes.
36  *
37  * Revision 1.10  1998/05/27 16:55:54  adam
38  * Minor changes.
39  *
40  * Revision 1.9  1998/03/31 11:07:45  adam
41  * Furhter work on UNIverse resource report.
42  * Added Extended Services handling in frontend server.
43  *
44  * Revision 1.8  1998/02/11 11:53:36  adam
45  * Changed code so that it compiles as C++.
46  *
47  * Revision 1.7  1998/02/10 11:03:57  adam
48  * Added support for extended handlers in backend server interface.
49  *
50  * Revision 1.6  1998/01/29 13:16:02  adam
51  * Added dummy sort in test server.
52  *
53  * Revision 1.5  1997/11/07 13:31:58  adam
54  * Added NT Service name part of statserv_options_block. Moved NT
55  * service utility to server library.
56  *
57  * Revision 1.4  1997/09/17 12:10:43  adam
58  * YAZ version 1.4.
59  *
60  * Revision 1.3  1997/09/09 10:10:20  adam
61  * Another MSV5.0 port. Changed projects to include proper
62  * library/include paths.
63  * Server starts server in test-mode when no options are given.
64  *
65  * Revision 1.2  1997/09/04 13:50:31  adam
66  * Bug fix in ztest.
67  *
68  */
69
70 /*
71  * Demonstration of simple server
72  */
73
74 #include <stdio.h>
75 #include <stdlib.h>
76 #include <ctype.h>
77 #include <assert.h>
78
79 #include <backend.h>
80 #include <xmalloc.h>
81 #include <proto.h>
82 #include <log.h>
83
84 Z_GenericRecord *read_grs1(FILE *f, ODR o);
85
86 int ztest_search (void *handle, bend_search_rr *rr);
87 int ztest_sort (void *handle, bend_sort_rr *rr);
88 int ztest_present (void *handle, bend_present_rr *rr);
89 int ztest_esrequest (void *handle, bend_esrequest_rr *rr);
90 int ztest_delete (void *handle, bend_delete_rr *rr);
91
92 bend_initresult *bend_init(bend_initrequest *q)
93 {
94     bend_initresult *r = (bend_initresult *) odr_malloc (q->stream, sizeof(*r));
95     static char *dummy = "Hej fister";
96
97     r->errcode = 0;
98     r->errstring = 0;
99     r->handle = dummy;
100     q->bend_sort = ztest_sort;       /* register sort handler */
101     q->bend_search = ztest_search;   /* register search handler */
102     q->bend_present = ztest_present; /* register present handle */
103     q->bend_esrequest = ztest_esrequest;
104     q->bend_delete = ztest_delete;
105     return r;
106 }
107
108 int ztest_search (void *handle, bend_search_rr *rr)
109 {
110     rr->hits = rand() % 22;
111     return 0;
112 }
113
114 int ztest_present (void *handle, bend_present_rr *rr)
115 {
116     return 0;
117 }
118
119 int ztest_esrequest (void *handle, bend_esrequest_rr *rr)
120 {
121     logf(LOG_LOG, "function: %d", *rr->esr->function);
122     if (rr->esr->packageName)
123         logf(LOG_LOG, "packagename: %s", rr->esr->packageName);
124     logf(LOG_LOG, "Waitaction: %d", *rr->esr->waitAction);
125
126     if (!rr->esr->taskSpecificParameters)
127     {
128         logf (LOG_WARN, "No task specific parameters");
129     }
130     else if (rr->esr->taskSpecificParameters->which != Z_External_itemOrder)
131     {
132         logf (LOG_WARN, "Not Item Order %d", rr->esr->taskSpecificParameters->which);
133     }
134     else
135     {
136         Z_ItemOrder *it = rr->esr->taskSpecificParameters->u.itemOrder;
137         switch (it->which)
138         {
139 #ifdef ASN_COMPILED
140         case Z_IOItemOrder_esRequest:
141 #else
142         case Z_ItemOrder_esRequest:
143 #endif
144         {
145             Z_IORequest *ir = it->u.esRequest;
146             Z_IOOriginPartToKeep *k = ir->toKeep;
147             Z_IOOriginPartNotToKeep *n = ir->notToKeep;
148             
149             if (k && k->contact)
150             {
151                 if (k->contact->name)
152                     logf(LOG_LOG, "contact name %s", k->contact->name);
153                 if (k->contact->phone)
154                     logf(LOG_LOG, "contact phone %s", k->contact->phone);
155                 if (k->contact->email)
156                     logf(LOG_LOG, "contact email %s", k->contact->email);
157             }
158             if (k->addlBilling)
159             {
160                 logf(LOG_LOG, "Billing info (not shown)");
161             }
162             
163             if (n->resultSetItem)
164             {
165                 logf(LOG_LOG, "resultsetItem");
166                 logf(LOG_LOG, "setId: %s", n->resultSetItem->resultSetId);
167                 logf(LOG_LOG, "item: %d", *n->resultSetItem->item);
168             }
169         }
170         break;
171         }
172     }
173     rr->errcode = 0;
174     return 0;
175 }
176
177 int ztest_delete (void *handle, bend_delete_rr *rr)
178 {
179     if (rr->num_setnames == 1 && !strcmp (rr->setnames[0], "1"))
180         rr->delete_status = Z_DeleteStatus_success;
181     else
182         rr->delete_status = Z_DeleteStatus_resultSetDidNotExist;
183     return 0;
184 }
185
186 /* Obsolete bend_search, never called because handler is registered */
187 bend_searchresult *bend_search(void *handle, bend_searchrequest *q, int *fd)
188 {
189     return 0;
190 }
191
192 /* Our sort handler really doesn't sort... */
193 int ztest_sort (void *handle, bend_sort_rr *rr)
194 {
195     rr->errcode = 0;
196     rr->sort_status = Z_SortStatus_success;
197     return 0;
198 }
199
200 static int atoin (const char *buf, int n)
201 {
202     int val = 0;
203     while (--n >= 0)
204     {
205         if (isdigit(*buf))
206             val = val*10 + (*buf - '0');
207         buf++;
208     }
209     return val;
210 }
211
212 char *marc_read(FILE *inf)
213 {
214     char length_str[5];
215     size_t size;
216     char *buf;
217
218     if (fread (length_str, 1, 5, inf) != 5)
219         return NULL;
220     size = atoin (length_str, 5);
221     if (size <= 6)
222         return NULL;
223     if (!(buf = (char*) xmalloc (size+1)))
224         return NULL;
225     if (fread (buf+5, 1, size-5, inf) != (size-5))
226     {
227         xfree (buf);
228         return NULL;
229     }
230     memcpy (buf, length_str, 5);
231     buf[size] = '\0';
232     return buf;
233 }
234
235 static char *dummy_database_record (int num)
236 {
237     FILE *inf = fopen ("dummy-records", "r");
238     char *buf = 0;
239
240     if (!inf)
241         return NULL;
242     while (--num >= 0)
243     {
244         if (buf)
245            xfree(buf);
246         if (num == 98)
247         {
248             buf = (char*) xmalloc(2101);
249             assert(buf);
250             memset(buf, 'A', 2100);
251             buf[2100] = '\0';
252             break;
253         }
254         else
255             buf = marc_read (inf);
256         if (!num || !buf)
257             break;
258     }
259     fclose(inf);
260     if (num < 0)
261         return 0;
262     return buf;
263 }
264
265 static Z_GenericRecord *dummy_grs_record (int num, ODR o)
266 {
267     FILE *f = fopen("dummy-grs", "r");
268     char line[512];
269     Z_GenericRecord *r = 0;
270     int n;
271
272     if (!f)
273         return 0;
274     while (fgets(line, 512, f))
275         if (*line == '#' && sscanf(line, "#%d", &n) == 1 && n == num)
276         {
277             r = read_grs1(f, o);
278             break;
279         }
280     fclose(f);
281     return r;
282 }
283
284 bend_fetchresult *bend_fetch(void *handle, bend_fetchrequest *q, int *fd)
285 {
286     bend_fetchresult *r = (bend_fetchresult *)
287                         odr_malloc (q->stream, sizeof(*r));
288     char *cp;
289     r->errstring = 0;
290     r->last_in_set = 0;
291     r->basename = "DUMMY";
292     r->format = q->format;  
293     if (q->format == VAL_SUTRS)
294     {
295         char buf[100];
296
297         sprintf(buf, "This is dummy SUTRS record number %d\n", q->number);
298         r->len = strlen(buf);
299         r->record = (char *) odr_malloc (q->stream, r->len+1);
300         strcpy(r->record, buf);
301     }
302     else if (q->format == VAL_GRS1)
303     {
304         r->len = -1;
305         r->record = (char*) dummy_grs_record(q->number, q->stream);
306         if (!r->record)
307         {
308             r->errcode = 13;
309             return r;
310         }
311     }
312     else if ((cp = dummy_database_record(q->number)))
313     {
314         r->len = strlen(cp);
315         r->record = (char *) odr_malloc (q->stream, 1+r->len);
316         strcpy (r->record, cp);
317         r->format = VAL_USMARC;
318     }
319     else
320     {
321         r->errcode = 13;
322         return r;
323     }
324     r->errcode = 0;
325     return r;
326 }
327
328 /*
329  * silly dummy-scan what reads words from a file.
330  */
331 bend_scanresult *bend_scan(void *handle, bend_scanrequest *q, int *fd)
332 {
333     bend_scanresult *r = (bend_scanresult *)
334         odr_malloc (q->stream, sizeof(*r));
335     static FILE *f = 0;
336     static struct scan_entry list[200];
337     static char entries[200][80];
338     int hits[200];
339     char term[80], *p;
340     int i, pos;
341
342     r->errcode = 0;
343     r->errstring = 0;
344     r->entries = list;
345     r->status = BEND_SCAN_SUCCESS;
346     if (!f && !(f = fopen("dummy-words", "r")))
347     {
348         perror("dummy-words");
349         exit(1);
350     }
351     if (q->term->term->which != Z_Term_general)
352     {
353         r->errcode = 229; /* unsupported term type */
354         return r;
355     }
356     if (q->term->term->u.general->len >= 80)
357     {
358         r->errcode = 11; /* term too long */
359         return r;
360     }
361     if (q->num_entries > 200)
362     {
363         r->errcode = 31;
364         return r;
365     }
366     memcpy(term, q->term->term->u.general->buf, q->term->term->u.general->len);
367     term[q->term->term->u.general->len] = '\0';
368     for (p = term; *p; p++)
369         if (islower(*p))
370             *p = toupper(*p);
371
372     fseek(f, 0, SEEK_SET);
373     r->num_entries = 0;
374     for (i = 0, pos = 0; fscanf(f, " %79[^:]:%d", entries[pos], &hits[pos]) == 2;
375         i++, pos < 199 ? pos++ : (pos = 0))
376     {
377         if (!r->num_entries && strcmp(entries[pos], term) >= 0) /* s-point fnd */
378         {
379             if ((r->term_position = q->term_position) > i + 1)
380             {
381                 r->term_position = i + 1;
382                 r->status = BEND_SCAN_PARTIAL;
383             }
384             for (; r->num_entries < r->term_position; r->num_entries++)
385             {
386                 int po;
387
388                 po = pos - r->term_position + r->num_entries + 1; /* find pos */
389                 if (po < 0)
390                     po += 200;
391
392                 if (!strcmp (term, "SD") && r->num_entries == 2)
393                 {
394                     list[r->num_entries].term = entries[pos];
395                     list[r->num_entries].occurrences = -1;
396                     list[r->num_entries].errcode = 233;
397                     list[r->num_entries].errstring = "SD for Scan Term";
398                 }
399                 else
400                 {
401                     list[r->num_entries].term = entries[po];
402                     list[r->num_entries].occurrences = hits[po];
403                 }
404             }
405         }
406         else if (r->num_entries)
407         {
408             list[r->num_entries].term = entries[pos];
409             list[r->num_entries].occurrences = hits[pos];
410             r->num_entries++;
411         }
412         if (r->num_entries >= q->num_entries)
413             break;
414     }
415     if (feof(f))
416         r->status = BEND_SCAN_PARTIAL;
417     return r;
418 }
419
420 void bend_close(void *handle)
421 {
422     return;
423 }
424
425 int main(int argc, char **argv)
426 {
427     return statserv_main(argc, argv);
428 }