Fixed bug in f_queryTypeDetails.
[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.10  1998-05-27 16:55:54  adam
11  * Minor changes.
12  *
13  * Revision 1.9  1998/03/31 11:07:45  adam
14  * Furhter work on UNIverse resource report.
15  * Added Extended Services handling in frontend server.
16  *
17  * Revision 1.8  1998/02/11 11:53:36  adam
18  * Changed code so that it compiles as C++.
19  *
20  * Revision 1.7  1998/02/10 11:03:57  adam
21  * Added support for extended handlers in backend server interface.
22  *
23  * Revision 1.6  1998/01/29 13:16:02  adam
24  * Added dummy sort in test server.
25  *
26  * Revision 1.5  1997/11/07 13:31:58  adam
27  * Added NT Service name part of statserv_options_block. Moved NT
28  * service utility to server library.
29  *
30  * Revision 1.4  1997/09/17 12:10:43  adam
31  * YAZ version 1.4.
32  *
33  * Revision 1.3  1997/09/09 10:10:20  adam
34  * Another MSV5.0 port. Changed projects to include proper
35  * library/include paths.
36  * Server starts server in test-mode when no options are given.
37  *
38  * Revision 1.2  1997/09/04 13:50:31  adam
39  * Bug fix in ztest.
40  *
41  */
42
43 /*
44  * Demonstration of simple server
45  */
46
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <ctype.h>
50 #include <assert.h>
51
52 #include <backend.h>
53 #include <xmalloc.h>
54 #include <proto.h>
55 #include <log.h>
56
57 Z_GenericRecord *read_grs1(FILE *f, ODR o);
58
59 int ztest_search (void *handle, bend_search_rr *rr);
60 int ztest_sort (void *handle, bend_sort_rr *rr);
61 int ztest_present (void *handle, bend_present_rr *rr);
62 int ztest_esrequest (void *handle, bend_esrequest_rr *rr);
63
64 bend_initresult *bend_init(bend_initrequest *q)
65 {
66     bend_initresult *r = (bend_initresult *) odr_malloc (q->stream, sizeof(*r));
67     static char *dummy = "Hej fister";
68
69     r->errcode = 0;
70     r->errstring = 0;
71     r->handle = dummy;
72     q->bend_sort = ztest_sort;       /* register sort handler */
73     q->bend_search = ztest_search;   /* register search handler */
74     q->bend_present = ztest_present; /* register present handle */
75     q->bend_esrequest = ztest_esrequest;
76     return r;
77 }
78
79 int ztest_search (void *handle, bend_search_rr *rr)
80 {
81     rr->hits = rand() % 22;
82     return 0;
83 }
84
85 int ztest_present (void *handle, bend_present_rr *rr)
86 {
87     return 0;
88 }
89
90 int ztest_esrequest (void *handle, bend_esrequest_rr *rr)
91 {
92     rr->errcode = 0;
93     return 0;
94 }
95
96 /* Obsolete bend_search, never called because handler is registered */
97 bend_searchresult *bend_search(void *handle, bend_searchrequest *q, int *fd)
98 {
99     return 0;
100 }
101
102 /* Our sort handler really doesn't sort... */
103 int ztest_sort (void *handle, bend_sort_rr *rr)
104 {
105     rr->errcode = 0;
106     rr->sort_status = Z_SortStatus_success;
107     return 0;
108 }
109
110 static int atoin (const char *buf, int n)
111 {
112     int val = 0;
113     while (--n >= 0)
114     {
115         if (isdigit(*buf))
116             val = val*10 + (*buf - '0');
117         buf++;
118     }
119     return val;
120 }
121
122 char *marc_read(FILE *inf)
123 {
124     char length_str[5];
125     size_t size;
126     char *buf;
127
128     if (fread (length_str, 1, 5, inf) != 5)
129         return NULL;
130     size = atoin (length_str, 5);
131     if (size <= 6)
132         return NULL;
133     if (!(buf = (char*) xmalloc (size+1)))
134         return NULL;
135     if (fread (buf+5, 1, size-5, inf) != (size-5))
136     {
137         xfree (buf);
138         return NULL;
139     }
140     memcpy (buf, length_str, 5);
141     buf[size] = '\0';
142     return buf;
143 }
144
145 static char *dummy_database_record (int num)
146 {
147     FILE *inf = fopen ("dummy-records", "r");
148     char *buf = 0;
149
150     if (!inf)
151         return NULL;
152     while (--num >= 0)
153     {
154         if (buf)
155            xfree(buf);
156         if (num == 98)
157         {
158             assert(buf = (char*) xmalloc(2101));
159             memset(buf, 'A', 2100);
160             buf[2100] = '\0';
161             break;
162         }
163         else
164             buf = marc_read (inf);
165         if (!num || !buf)
166             break;
167     }
168     fclose(inf);
169     if (num < 0)
170         return 0;
171     return buf;
172 }
173
174 static Z_GenericRecord *dummy_grs_record (int num, ODR o)
175 {
176     FILE *f = fopen("dummy-grs", "r");
177     char line[512];
178     Z_GenericRecord *r = 0;
179     int n;
180
181     if (!f)
182         return 0;
183     while (fgets(line, 512, f))
184         if (*line == '#' && sscanf(line, "#%d", &n) == 1 && n == num)
185         {
186             r = read_grs1(f, o);
187             break;
188         }
189     fclose(f);
190     return r;
191 }
192
193 bend_fetchresult *bend_fetch(void *handle, bend_fetchrequest *q, int *num)
194 {
195     bend_fetchresult *r = (bend_fetchresult *)
196                         odr_malloc (q->stream, sizeof(*r));
197     char *cp;
198     r->errstring = 0;
199     r->last_in_set = 0;
200     r->basename = "DUMMY";
201     r->format = q->format;  
202     if (q->format == VAL_SUTRS)
203     {
204         char buf[100];
205
206         sprintf(buf, "This is dummy SUTRS record number %d\n", q->number);
207         r->len = strlen(buf);
208         r->record = odr_malloc (q->stream, r->len+1);
209         strcpy(r->record, buf);
210     }
211     else if (q->format == VAL_GRS1)
212     {
213         r->len = -1;
214         r->record = (char*) dummy_grs_record(q->number, q->stream);
215         if (!r->record)
216         {
217             r->errcode = 13;
218             return r;
219         }
220     }
221     else if ((cp = dummy_database_record(q->number)))
222     {
223         r->len = strlen(cp);
224         r->record = (char *) odr_malloc (q->stream, 1+r->len);
225         strcpy (r->record, cp);
226         r->format = VAL_USMARC;
227     }
228     else
229     {
230         r->errcode = 13;
231         return r;
232     }
233     r->errcode = 0;
234     return r;
235 }
236
237 bend_deleteresult *bend_delete(void *handle, bend_deleterequest *q, int *num)
238 {
239     return 0;
240 }
241
242 /*
243  * silly dummy-scan what reads words from a file.
244  */
245 bend_scanresult *bend_scan(void *handle, bend_scanrequest *q, int *num)
246 {
247     bend_scanresult *r = (bend_scanresult *) odr_malloc (q->stream, sizeof(*r));
248     static FILE *f = 0;
249     static struct scan_entry list[200];
250     static char entries[200][80];
251     int hits[200];
252     char term[80], *p;
253     int i, pos;
254
255     r->errcode = 0;
256     r->errstring = 0;
257     r->entries = list;
258     r->status = BEND_SCAN_SUCCESS;
259     if (!f && !(f = fopen("dummy-words", "r")))
260     {
261         perror("dummy-words");
262         exit(1);
263     }
264     if (q->term->term->which != Z_Term_general)
265     {
266         r->errcode = 229; /* unsupported term type */
267         return r;
268     }
269     if (q->term->term->u.general->len >= 80)
270     {
271         r->errcode = 11; /* term too long */
272         return r;
273     }
274     if (q->num_entries > 200)
275     {
276         r->errcode = 31;
277         return r;
278     }
279     memcpy(term, q->term->term->u.general->buf, q->term->term->u.general->len);
280     term[q->term->term->u.general->len] = '\0';
281     for (p = term; *p; p++)
282         if (islower(*p))
283             *p = toupper(*p);
284
285     fseek(f, 0, SEEK_SET);
286     r->num_entries = 0;
287     for (i = 0, pos = 0; fscanf(f, " %79[^:]:%d", entries[pos], &hits[pos]) == 2;
288         i++, pos < 199 ? pos++ : (pos = 0))
289     {
290         if (!r->num_entries && strcmp(entries[pos], term) >= 0) /* s-point fnd */
291         {
292             if ((r->term_position = q->term_position) > i + 1)
293             {
294                 r->term_position = i + 1;
295                 r->status = BEND_SCAN_PARTIAL;
296             }
297             for (; r->num_entries < r->term_position; r->num_entries++)
298             {
299                 int po;
300
301                 po = pos - r->term_position + r->num_entries + 1; /* find pos */
302                 if (po < 0)
303                     po += 200;
304                 list[r->num_entries].term = entries[po];
305                 list[r->num_entries].occurrences = hits[po];
306             }
307         }
308         else if (r->num_entries)
309         {
310             list[r->num_entries].term = entries[pos];
311             list[r->num_entries].occurrences = hits[pos];
312             r->num_entries++;
313         }
314         if (r->num_entries >= q->num_entries)
315             break;
316     }
317     if (feof(f))
318         r->status = BEND_SCAN_PARTIAL;
319     return r;
320 }
321
322 void bend_close(void *handle)
323 {
324     return;
325 }
326
327 int main(int argc, char **argv)
328 {
329     return statserv_main(argc, argv);
330 }