Added authentication check facility to zebra.
[idzebra-moved-to-github.git] / index / zebraapi.c
1 /*
2  * Copyright (C) 1995-1998, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: zebraapi.c,v $
7  * Revision 1.6  1998-06-22 11:36:47  adam
8  * Added authentication check facility to zebra.
9  *
10  * Revision 1.5  1998/06/13 00:14:08  adam
11  * Minor changes.
12  *
13  * Revision 1.4  1998/06/12 12:22:12  adam
14  * Work on Zebra API.
15  *
16  * Revision 1.3  1998/05/27 16:57:44  adam
17  * Zebra returns surrogate diagnostic for single records when
18  * appropriate.
19  *
20  * Revision 1.2  1998/05/20 10:12:19  adam
21  * Implemented automatic EXPLAIN database maintenance.
22  * Modified Zebra to work with ASN.1 compiled version of YAZ.
23  *
24  * Revision 1.1  1998/03/05 08:45:13  adam
25  * New result set model and modular ranking system. Moved towards
26  * descent server API. System information stored as "SGML" records.
27  *
28  */
29
30 #include <stdio.h>
31 #ifdef WINDOWS
32 #include <io.h>
33 #include <process.h>
34 #else
35 #include <unistd.h>
36 #endif
37
38 #include <diagbib1.h>
39 #include "zserver.h"
40
41 static int zebra_register_lock (ZebraHandle zh)
42 {
43     time_t lastChange;
44     int state = zebra_server_lock_get_state(zh, &lastChange);
45
46     switch (state)
47     {
48     case 'c':
49         state = 1;
50         break;
51     default:
52         state = 0;
53     }
54     zebra_server_lock (zh, state);
55 #if USE_TIMES
56     times (&zh->tms1);
57 #endif
58     if (zh->registerState == state)
59     {
60         if (zh->registerChange >= lastChange)
61             return 0;
62         logf (LOG_LOG, "Register completely updated since last access");
63     }
64     else if (zh->registerState == -1)
65         logf (LOG_LOG, "Reading register using state %d pid=%ld", state,
66               (long) getpid());
67     else
68         logf (LOG_LOG, "Register has changed state from %d to %d",
69               zh->registerState, state);
70     zh->registerChange = lastChange;
71     if (zh->records)
72     {
73         zebraExplain_close (zh->zei, 0, 0);
74         dict_close (zh->dict);
75         sortIdx_close (zh->sortIdx);
76         if (zh->isam)
77             is_close (zh->isam);
78         if (zh->isamc)
79             isc_close (zh->isamc);
80         rec_close (&zh->records);
81     }
82     bf_cache (zh->bfs, state ? res_get (zh->res, "shadow") : NULL);
83     zh->registerState = state;
84     zh->records = rec_open (zh->bfs, 0);
85     if (!(zh->dict = dict_open (zh->bfs, FNAME_DICT, 40, 0)))
86         return -1;
87     if (!(zh->sortIdx = sortIdx_open (zh->bfs, 0)))
88         return -1;
89     zh->isam = NULL;
90     zh->isamc = NULL;
91     if (!res_get_match (zh->res, "isam", "i", NULL))
92     {
93         if (!(zh->isamc = isc_open (zh->bfs, FNAME_ISAMC,
94                                     0, key_isamc_m(zh->res))))
95             return -1;
96
97     }
98     else
99     {
100         if (!(zh->isam = is_open (zh->bfs, FNAME_ISAM, key_compare, 0,
101                                   sizeof (struct it_key), zh->res)))
102             return -1;
103     }
104     zh->zei = zebraExplain_open (zh->records, zh->dh, zh->res, 0, 0, 0);
105
106     return 0;
107 }
108
109 static void zebra_register_unlock (ZebraHandle zh)
110 {
111     static int waitSec = -1;
112
113 #if USE_TIMES
114     times (&zh->tms2);
115     logf (LOG_LOG, "user/system: %ld/%ld",
116                         (long) (zh->tms2.tms_utime - zh->tms1.tms_utime),
117                         (long) (zh->tms2.tms_stime - zh->tms1.tms_stime));
118 #endif
119     if (waitSec == -1)
120     {
121         char *s = res_get (zh->res, "debugRequestWait");
122         if (s)
123             waitSec = atoi (s);
124         else
125             waitSec = 0;
126     }
127 #ifdef WINDOWS
128 #else
129     if (waitSec > 0)
130         sleep (waitSec);
131 #endif
132     if (zh->registerState != -1)
133         zebra_server_unlock (zh, zh->registerState);
134 }
135
136 ZebraHandle zebra_open (const char *configName)
137 {
138     ZebraHandle zh = xmalloc (sizeof(*zh));
139
140     if (!(zh->res = res_open (configName)))
141     {
142         logf (LOG_WARN, "Failed to read resources `%s'", configName);
143         return NULL;
144     }
145     zebra_server_lock_init (zh);
146     zh->dh = data1_create ();
147     zh->bfs = bfs_create (res_get (zh->res, "register"));
148     bf_lockDir (zh->bfs, res_get (zh->res, "lockDir"));
149     data1_set_tabpath (zh->dh, res_get(zh->res, "profilePath"));
150     zh->sets = NULL;
151     zh->registerState = -1;  /* trigger open of registers! */
152     zh->registerChange = 0;
153     
154     zh->records = NULL;
155     zh->zebra_maps = zebra_maps_open (zh->res);
156     zh->rank_classes = NULL;
157     zh->errCode = 0;
158     zh->errString = 0;
159     
160     zebraRankInstall (zh, rank1_class);
161
162     if (!res_get (zh->res, "passwd"))
163         zh->passwd_db = NULL;
164     else
165     {
166         zh->passwd_db = passwd_db_open ();
167         if (!zh->passwd_db)
168             logf (LOG_WARN|LOG_ERRNO, "passwd_db_open failed");
169         else
170             passwd_db_file (zh->passwd_db, res_get (zh->res, "passwd"));
171     }
172     zh->bfs = bfs_create (res_get (zh->res, "register"));
173     bf_lockDir (zh->bfs, res_get (zh->res, "lockDir"));
174     data1_set_tabpath (zh->dh, res_get(zh->res, "profilePath"));
175
176     return zh;
177 }
178
179 void zebra_close (ZebraHandle zh)
180 {
181     if (zh->records)
182     {
183         resultSetDestroy (zh);
184         zebraExplain_close (zh->zei, 0, 0);
185         dict_close (zh->dict);
186         sortIdx_close (zh->sortIdx);
187         if (zh->isam)
188             is_close (zh->isam);
189         if (zh->isamc)
190             isc_close (zh->isamc);
191         rec_close (&zh->records);
192         zebra_register_unlock (zh);
193     }
194     zebra_maps_close (zh->zebra_maps);
195     zebraRankDestroy (zh);
196     bfs_destroy (zh->bfs);
197     data1_destroy (zh->dh);
198     zebra_server_lock_destroy (zh);
199
200     if (zh->passwd_db)
201         passwd_db_close (zh->passwd_db);
202     res_close (zh->res);
203     xfree (zh);
204 }
205
206 void zebra_search_rpn (ZebraHandle zh, ODR stream,
207                        Z_RPNQuery *query, int num_bases, char **basenames, 
208                        const char *setname)
209 {
210     zebra_register_lock (zh);
211     zh->errCode = 0;
212     zh->errString = NULL;
213     zh->hits = 0;
214     rpn_search (zh, stream, query, num_bases, basenames, setname);
215     zebra_register_unlock (zh);
216 }
217
218 void zebra_records_retrieve (ZebraHandle zh, ODR stream,
219                              const char *setname, Z_RecordComposition *comp,
220                              oid_value input_format, int num_recs,
221                              ZebraRetrievalRecord *recs)
222 {
223     ZebraPosSet poset;
224     int i, *pos_array;
225
226     zh->errCode = 0;
227     zh->errString = NULL;
228     pos_array = xmalloc (num_recs * sizeof(*pos_array));
229     for (i = 0; i<num_recs; i++)
230         pos_array[i] = recs[i].position;
231
232     zebra_register_lock (zh);
233
234     poset = zebraPosSetCreate (zh, setname, num_recs, pos_array);
235     if (!poset)
236     {
237         logf (LOG_DEBUG, "zebraPosSetCreate error");
238         zh->errCode = 13;
239     }
240     else
241     {
242         for (i = 0; i<num_recs; i++)
243         {
244             if (!poset[i].sysno)
245             {
246                 zh->errCode = 13;
247                 logf (LOG_DEBUG, "Out of range. pos=%d", pos_array[i]);
248             }
249             else
250             {
251                 recs[i].errCode =
252                     zebra_record_fetch (zh, poset[i].sysno, poset[i].score,
253                                         stream, input_format, comp,
254                                         &recs[i].format, &recs[i].buf,
255                                         &recs[i].len,
256                                         &recs[i].base);
257                 recs[i].errString = NULL;
258             }
259         }
260         zebraPosSetDestroy (zh, poset, num_recs);
261     }
262     zebra_register_unlock (zh);
263     xfree (pos_array);
264 }
265
266 void zebra_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
267                  oid_value attributeset,
268                  int num_bases, char **basenames,
269                  int *position, int *num_entries, ZebraScanEntry **entries,
270                  int *is_partial)
271 {
272     zh->errCode = 0;
273     zh->errString = NULL;
274     zebra_register_lock (zh);
275     rpn_scan (zh, stream, zapt, attributeset,
276               num_bases, basenames, position,
277               num_entries, entries, is_partial);
278     zebra_register_unlock (zh);
279 }
280
281 void zebra_sort (ZebraHandle zh, ODR stream,
282                  int num_input_setnames, char **input_setnames,
283                  char *output_setname, Z_SortKeySpecList *sort_sequence,
284                  int *sort_status)
285 {
286     zh->errCode = 0;
287     zh->errString = NULL;
288     zebra_register_lock (zh);
289     resultSetSort (zh, stream, num_input_setnames, input_setnames,
290                    output_setname, sort_sequence, sort_status);
291     zebra_register_unlock (zh);
292 }
293
294 int zebra_errCode (ZebraHandle zh)
295 {
296     return zh->errCode;
297 }
298
299 const char *zebra_errString (ZebraHandle zh)
300 {
301     return diagbib1_str (zh->errCode);
302 }
303
304 char *zebra_errAdd (ZebraHandle zh)
305 {
306     return zh->errString;
307 }
308
309 int zebra_hits (ZebraHandle zh)
310 {
311     return zh->hits;
312 }
313
314 int zebra_auth (ZebraHandle zh, const char *user, const char *pass)
315 {
316     if (!zh->passwd_db || !passwd_db_auth (zh->passwd_db, user, pass))
317         return 0;
318     return 1;
319 }
320
321 void zebra_setDB (ZebraHandle zh, int num_bases, char **basenames)
322 {
323
324 }
325
326 void zebra_setRecordType (ZebraHandle zh, const char *type)
327 {
328
329 }
330
331 void zebra_setGroup (ZebraHandle zh, const char *group)
332 {
333
334 }
335
336 void zebra_admin (ZebraHandle zh, const char *command)
337 {
338
339 }