YAZ  5.34.0
zoom-c.c
Go to the documentation of this file.
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
9 #if HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12 
13 #include <assert.h>
14 #include <string.h>
15 #include <errno.h>
16 #include "zoom-p.h"
17 
18 #include <yaz/yaz-util.h>
19 #include <yaz/xmalloc.h>
20 #include <yaz/otherinfo.h>
21 #include <yaz/log.h>
22 #include <yaz/diagbib1.h>
23 #include <yaz/charneg.h>
24 #include <yaz/query-charset.h>
25 #include <yaz/snprintf.h>
26 #include <yaz/facet.h>
27 
28 #include <yaz/shptr.h>
29 
30 #if SHPTR
32 #endif
33 
34 static int log_api0 = 0;
35 static int log_details0 = 0;
36 
37 static void resultset_destroy(ZOOM_resultset r);
38 static zoom_ret do_write_ex(ZOOM_connection c, char *buf_out, int len_out);
39 
40 static void initlog(void)
41 {
42  static int log_level_initialized = 0;
43 
45  {
47  log_details0 = yaz_log_module_level("zoomdetails");
49  }
50 }
51 
52 static zoom_ret send_HTTP_redirect(ZOOM_connection c, const char *uri);
53 
55  const char *dset,
56  const char *addinfo, const char *addinfo2)
57 {
58  char *cp;
59 
60  xfree(c->addinfo);
61  c->addinfo = 0;
62  c->error = error;
63  if (!c->diagset || strcmp(dset, c->diagset))
64  {
65  xfree(c->diagset);
66  c->diagset = xstrdup(dset);
67  /* remove integer part from SRW diagset .. */
68  if ((cp = strrchr(c->diagset, '/')))
69  *cp = '\0';
70  }
71  if (addinfo && addinfo2)
72  {
73  c->addinfo = (char*) xmalloc(strlen(addinfo) + strlen(addinfo2) + 3);
74  strcpy(c->addinfo, addinfo);
75  strcat(c->addinfo, ": ");
76  strcat(c->addinfo, addinfo2);
77  }
78  else if (addinfo)
79  c->addinfo = xstrdup(addinfo);
80  if (error != ZOOM_ERROR_NONE)
81  {
82  yaz_log(c->log_api, "%p set_dset_error %s %s:%d %s %s",
83  c, c->host_port ? c->host_port : "<>", dset, error,
84  addinfo ? addinfo : "",
85  addinfo2 ? addinfo2 : "");
86  }
87 }
88 
89 int ZOOM_uri_to_code(const char *uri)
90 {
91  int code = 0;
92  const char *cp;
93  if ((cp = strrchr(uri, '/')))
94  code = atoi(cp+1);
95  return code;
96 }
97 
98 void ZOOM_set_error(ZOOM_connection c, int error, const char *addinfo)
99 {
100  ZOOM_set_dset_error(c, error, "ZOOM", addinfo, 0);
101 }
102 
104 {
105  /*
106  * If an error is tied to an operation then it's ok to clear: for
107  * example, a diagnostic returned from a search is cleared by a
108  * subsequent search. However, problems such as Connection Lost
109  * or Init Refused are not cleared, because they are not
110  * recoverable: doing another search doesn't help.
111  */
112 
114  switch (c->error)
115  {
116  case ZOOM_ERROR_CONNECT:
117  case ZOOM_ERROR_MEMORY:
118  case ZOOM_ERROR_DECODE:
120  case ZOOM_ERROR_INIT:
121  case ZOOM_ERROR_INTERNAL:
123  break;
124  default:
126  }
127 }
128 
130 {
131  switch(task->which)
132  {
133  case ZOOM_TASK_SEARCH:
134  yaz_log(YLOG_LOG, "search p=%p", task);
135  break;
136  case ZOOM_TASK_CONNECT:
137  yaz_log(YLOG_LOG, "connect p=%p", task);
138  break;
139  case ZOOM_TASK_SCAN:
140  yaz_log(YLOG_LOG, "scan p=%p", task);
141  break;
142  }
143 }
144 
146 {
147  ZOOM_task task;
148  yaz_log(YLOG_LOG, "connection p=%p tasks", c);
149  for (task = c->tasks; task; task = task->next)
151 }
152 
154 {
155  ZOOM_task *taskp = &c->tasks;
156  while (*taskp)
157  taskp = &(*taskp)->next;
158  *taskp = (ZOOM_task) xmalloc(sizeof(**taskp));
159  (*taskp)->running = 0;
160  (*taskp)->which = which;
161  (*taskp)->next = 0;
162  clear_error(c);
163  return *taskp;
164 }
165 
167 {
168  return c->tasks ? 0 : 1;
169 }
170 
172 {
173  ZOOM_task task = (ZOOM_task) xmalloc(sizeof(*task));
174 
175  task->next = c->tasks;
176  c->tasks = task;
177 
178  task->running = 0;
179  task->which = which;
180  return task;
181 }
182 
184 {
185  ZOOM_task task = c->tasks;
186 
187  if (task)
188  {
189  c->tasks = task->next;
190  switch (task->which)
191  {
192  case ZOOM_TASK_SEARCH:
193  resultset_destroy(task->u.search.resultset);
194  xfree(task->u.search.syntax);
195  xfree(task->u.search.elementSetName);
196  xfree(task->u.search.schema);
197  break;
198  case ZOOM_TASK_CONNECT:
199  break;
200  case ZOOM_TASK_SCAN:
201  ZOOM_scanset_destroy(task->u.scan.scan);
202  break;
203  case ZOOM_TASK_PACKAGE:
205  break;
206  case ZOOM_TASK_SORT:
207  resultset_destroy(task->u.sort.resultset);
208  ZOOM_query_destroy(task->u.sort.q);
209  break;
210  default:
211  assert(0);
212  }
213  xfree(task);
214 
215  if (!c->tasks)
216  {
218  ZOOM_connection_put_event(c, event);
219  }
220  }
221 }
222 
224 {
225  while (c->tasks)
227 }
228 
229 static void odr_wrbuf_write(ODR o, void *handle, int type,
230  const char *buf, int len)
231 {
232  WRBUF w = (WRBUF) handle;
233  wrbuf_write(w, buf, len);
234 }
235 
238 {
239  ZOOM_connection c = (ZOOM_connection) xmalloc(sizeof(*c));
240 
241  initlog();
242 
243  c->log_api = log_api0;
245 
246  yaz_log(c->log_api, "%p ZOOM_connection_create", c);
247 
248  c->proto = PROTO_Z3950;
249  c->cs = 0;
251  c->reconnect_ok = 0;
252  c->state = STATE_IDLE;
253  c->addinfo = 0;
254  c->diagset = 0;
256  c->buf_in = 0;
257  c->len_in = 0;
258  c->buf_out = 0;
259  c->len_out = 0;
260  c->resultsets = 0;
261 
263 
264  c->host_port = 0;
265  c->proxy = 0;
266  c->tproxy = 0;
267  c->proxy_mode = 0;
268 
269  c->charset = c->lang = 0;
270 
271  c->cookie_out = 0;
272  c->cookie_in = 0;
273  c->client_IP = 0;
274  c->tasks = 0;
275 
276  c->user = 0;
277  c->group = 0;
278  c->password = 0;
279  c->url_authentication = 0;
280 
281  c->maximum_record_size = 0;
282  c->preferred_message_size = 0;
283 
286  c->odr_print = 0;
287  c->odr_save = 0;
288 
289  c->async = 0;
292 
293  c->m_queue_front = 0;
294  c->m_queue_back = 0;
295 
296  c->sru_version = 0;
297  c->no_redirects = 0;
298  c->cookies = 0;
299  c->location = 0;
300  c->saveAPDU_wrbuf = 0;
301 
303  return c;
304 }
305 
306 ZOOM_API(void) ZOOM_connection_save_apdu_wrbuf(ZOOM_connection c, WRBUF w)
307 {
308  if (c->odr_save)
309  {
310  odr_destroy(c->odr_save);
311  c->odr_save = 0;
312  }
313  if (w)
314  {
317  }
318 }
319 
320 /* set database names. Take local databases (if set); otherwise
321  take databases given in ZURL (if set); otherwise use Default */
323  int *num, ODR odr)
324 {
325  char **databaseNames;
326  const char *cp = ZOOM_options_get(options, "databaseName");
327 
328  if ((!cp || !*cp) && con->host_port)
329  cs_get_host_args(con->host_port, &cp);
330  if (!cp || !*cp)
331  cp = "Default";
332  nmem_strsplit(odr_getmem(odr), "+", cp, &databaseNames, num);
333  return databaseNames;
334 }
335 
337  ZOOM_connection_new(const char *host, int portnum)
338 {
340 
341  ZOOM_connection_connect(c, host, portnum);
342  return c;
343 }
344 
346 {
347  if (!s || !*s)
348  return zoom_sru_soap;
349  if (!yaz_matchstr(s, "soap"))
350  return zoom_sru_soap;
351  else if (!yaz_matchstr(s, "get"))
352  return zoom_sru_get;
353  else if (!yaz_matchstr(s, "post"))
354  return zoom_sru_post;
355  else if (!yaz_matchstr(s, "solr"))
356  return zoom_sru_solr;
357  return zoom_sru_error;
358 }
359 
360 ZOOM_API(void)
362  const char *host, int portnum)
363 {
364  const char *val;
365 
366  initlog();
367 
368  yaz_log(c->log_api, "%p ZOOM_connection_connect host=%s portnum=%d",
369  c, host ? host : "null", portnum);
370 
373 
374  if (c->cs)
375  {
376  yaz_log(c->log_details, "%p ZOOM_connection_connect reconnect ok", c);
377  c->reconnect_ok = 1;
378  return;
379  }
380  yaz_log(c->log_details, "%p ZOOM_connection_connect connect", c);
381  xfree(c->proxy);
382  c->proxy = 0;
383  val = ZOOM_options_get(c->options, "proxy");
384  if (val && *val)
385  {
386  yaz_log(c->log_details, "%p ZOOM_connection_connect proxy=%s", c, val);
387  c->proxy = xstrdup(val);
388  }
389 
390  xfree(c->tproxy);
391  c->tproxy = 0;
392  val = ZOOM_options_get(c->options, "tproxy");
393  if (val && *val)
394  {
395  yaz_log(c->log_details, "%p ZOOM_connection_connect tproxy=%s", c, val);
396  c->tproxy = xstrdup(val);
397  }
398 
399  xfree(c->charset);
400  c->charset = 0;
401  val = ZOOM_options_get(c->options, "charset");
402  if (val && *val)
403  {
404  yaz_log(c->log_details, "%p ZOOM_connection_connect charset=%s", c, val);
405  c->charset = xstrdup(val);
406  }
407 
408  xfree(c->lang);
409  val = ZOOM_options_get(c->options, "lang");
410  if (val && *val)
411  {
412  yaz_log(c->log_details, "%p ZOOM_connection_connect lang=%s", c, val);
413  c->lang = xstrdup(val);
414  }
415  else
416  c->lang = 0;
417 
418  if (host)
419  {
420  char hostn[128];
421  const char *http_lead;
422 
423  val = ZOOM_options_get(c->options, "sru");
424  if (val && *val && !strstr(host, "://"))
425  http_lead = "http://";
426  else
427  http_lead = "";
428  c->sru_mode = get_sru_mode_from_string(val);
429 
430  xfree(c->host_port);
431  if (portnum)
432  {
433  sprintf(hostn, "%.80s:%d", host, portnum);
434  host = hostn;
435  }
436  c->host_port = xmalloc(strlen(host) + strlen(http_lead) + 1);
437  strcpy(c->host_port, http_lead);
438  strcat(c->host_port, host);
439  }
440 
441  {
442  /*
443  * If the "<scheme>:" part of the host string is preceded by one
444  * or more comma-separated <name>=<value> pairs, these are taken
445  * to be options to be set on the connection object. Among other
446  * applications, this facility can be used to embed authentication
447  * in a host string:
448  * user=admin,password=secret,tcp:localhost:9999
449  */
450  char *remainder = c->host_port;
451  char *pcolon = strchr(remainder, ':');
452  char *pcomma;
453  char *pequals;
454  while ((pcomma = strchr(remainder, ',')) != 0 &&
455  (pcolon == 0 || pcomma < pcolon))
456  {
457  *pcomma = '\0';
458  if ((pequals = strchr(remainder, '=')) != 0)
459  {
460  *pequals = '\0';
461  ZOOM_connection_option_set(c, remainder, pequals+1);
462  }
463  remainder = pcomma+1;
464  }
465 
466  if (remainder != c->host_port)
467  {
468  remainder = xstrdup(remainder);
469  xfree(c->host_port);
470  c->host_port = remainder;
471  }
472  }
473 
474  xfree(c->sru_version);
475  val = ZOOM_options_get(c->options, "sru_version");
476  c->sru_version = xstrdup(val ? val : "1.2");
477 
478  ZOOM_options_set(c->options, "host", c->host_port);
479 
480  xfree(c->cookie_out);
481  c->cookie_out = 0;
482  val = ZOOM_options_get(c->options, "cookie");
483  if (val && *val)
484  {
485  yaz_log(c->log_details, "%p ZOOM_connection_connect cookie=%s", c, val);
486  c->cookie_out = xstrdup(val);
487  }
488 
489  xfree(c->client_IP);
490  c->client_IP = 0;
491  val = ZOOM_options_get(c->options, "clientIP");
492  if (val && *val)
493  {
494  yaz_log(c->log_details, "%p ZOOM_connection_connect clientIP=%s",
495  c, val);
496  c->client_IP = xstrdup(val);
497  }
498 
499  xfree(c->group);
500  c->group = 0;
501  val = ZOOM_options_get(c->options, "group");
502  if (val && *val)
503  c->group = xstrdup(val);
504 
505  xfree(c->user);
506  c->user = 0;
507  val = ZOOM_options_get(c->options, "user");
508  if (val && *val)
509  c->user = xstrdup(val);
510 
511  xfree(c->password);
512  c->password = 0;
513  val = ZOOM_options_get(c->options, "password");
514  if (!val)
515  val = ZOOM_options_get(c->options, "pass");
516  if (val && *val)
517  c->password = xstrdup(val);
518 
519  val = ZOOM_options_get(c->options, "authenticationMode");
520  if (val && !strcmp(val, "url"))
521  c->url_authentication = 1;
522  else
523  c->url_authentication = 0;
524 
525  c->maximum_record_size =
526  ZOOM_options_get_int(c->options, "maximumRecordSize", 64*1024*1024);
527  c->preferred_message_size =
528  ZOOM_options_get_int(c->options, "preferredMessageSize", 64*1024*1024);
529 
530  c->async = ZOOM_options_get_bool(c->options, "async", 0);
531 
532  yaz_cookies_destroy(c->cookies);
533  c->cookies = yaz_cookies_create();
534 
536  {
538  return;
539  }
540  if (c->sru_mode == zoom_sru_error)
541  {
544  return;
545  }
546 
547  if (c->odr_print)
548  odr_destroy(c->odr_print);
549  c->odr_print = 0;
550  val = ZOOM_options_get(c->options, "apdufile");
551  if (val)
552  {
553  c->odr_print = odr_createmem(ODR_PRINT);
554  if (strcmp(val, "-"))
555  {
556  FILE *f = fopen(val, "a");
557  if (!f)
558  {
559  WRBUF w = wrbuf_alloc();
560  wrbuf_printf(w, "fopen: %s", val);
562  wrbuf_destroy(w);
563  return;
564  }
565  odr_setprint(c->odr_print, f);
566  }
567  }
568  else if (ZOOM_options_get_bool(c->options, "apdulog", 0))
569  {
570  c->odr_print = odr_createmem(ODR_PRINT);
571  odr_setprint_noclose(c->odr_print, yaz_log_file());
572  }
573 
574  yaz_log(c->log_details, "%p ZOOM_connection_connect async=%d", c, c->async);
576 
577  if (!c->async)
578  {
579  while (ZOOM_event(1, &c))
580  ;
581  }
582 }
583 
585 {
586  if (r->connection)
587  {
588  /* remove ourselves from the resultsets in connection */
590  while (1)
591  {
592  assert(*rp); /* we must be in this list!! */
593  if (*rp == r)
594  { /* OK, we're here - take us out of it */
595  *rp = (*rp)->next;
596  break;
597  }
598  rp = &(*rp)->next;
599  }
600  r->connection = 0;
601  }
602 }
603 
604 ZOOM_API(void)
606 {
607  ZOOM_resultset r;
608  if (!c)
609  return;
610  yaz_log(c->log_api, "%p ZOOM_connection_destroy", c);
611 
613  if (c->cs)
614  cs_close(c->cs);
615 
616  for (r = c->resultsets; r; r = r->next)
617  r->connection = 0;
618 
619  xfree(c->buf_in);
620  xfree(c->addinfo);
621  xfree(c->diagset);
622  odr_destroy(c->odr_in);
623  odr_destroy(c->odr_out);
624  if (c->odr_save)
625  odr_destroy(c->odr_save);
626  if (c->odr_print)
627  odr_destroy(c->odr_print);
628  ZOOM_options_destroy(c->options);
631  xfree(c->host_port);
632  xfree(c->proxy);
633  xfree(c->tproxy);
634  xfree(c->charset);
635  xfree(c->lang);
636  xfree(c->cookie_out);
637  xfree(c->cookie_in);
638  xfree(c->client_IP);
639  xfree(c->user);
640  xfree(c->group);
641  xfree(c->password);
642  xfree(c->sru_version);
643  xfree(c->location);
644  yaz_cookies_destroy(c->cookies);
645  wrbuf_destroy(c->saveAPDU_wrbuf);
646  xfree(c);
647 }
648 
650 {
651  if (r)
652  {
654  (r->refcount)++;
655  yaz_log(log_details0, "%p ZOOM_resultset_addref count=%d",
656  r, r->refcount);
658  }
659 }
660 
661 static int g_resultsets = 0;
663 
664 /* TODO We need to initialize this before running threaded:
665  * call resultset_use(0) */
666 
667 static int resultset_use(int delta) {
668  int resultset_count;
669  if (g_resultset_mutex == 0)
672  g_resultsets += delta;
673  resultset_count = g_resultsets;
675  return resultset_count;
676 }
677 
678 int resultsets_count(void) {
679  return resultset_use(0);
680 }
681 
683 {
684  int i;
685  ZOOM_resultset r = (ZOOM_resultset) xmalloc(sizeof(*r));
686 
687  initlog();
688 
689  yaz_log(log_details0, "%p ZOOM_resultset_create", r);
690  r->refcount = 1;
691  r->size = 0;
693  r->piggyback = 1;
694  r->setname = 0;
695  r->step = 0;
696  for (i = 0; i<RECORD_HASH_SIZE; i++)
697  r->record_hash[i] = 0;
698  r->r_sort_spec = 0;
699  r->query = 0;
700  r->connection = 0;
701  r->databaseNames = 0;
702  r->num_databaseNames = 0;
703  r->req_facets = 0;
704  r->res_facets = 0;
705  r->num_res_facets = 0;
706  r->facets_names = 0;
707  r->mutex = 0;
708  yaz_mutex_create(&r->mutex);
709 #if SHPTR
710  {
711  WRBUF w = wrbuf_alloc();
713  }
714 #endif
715  resultset_use(1);
716  r->mc_key = 0;
717  r->live_set = 0;
718  return r;
719 }
720 
723 {
724  ZOOM_resultset r;
726 
727  ZOOM_query_prefix(s, q);
728 
729  r = ZOOM_connection_search(c, s);
731  return r;
732 }
733 
736 {
738  ZOOM_task task;
739  int start, count;
740  const char *syntax, *elementSetName, *schema;
741  yaz_log(c->log_api, "%p ZOOM_connection_search set %p query %p", c, r, q);
743  r->query = q;
745 
746  r->options = ZOOM_options_create_with_parent(c->options);
747 
749  ZOOM_options_get(r->options, "facets"));
750  start = ZOOM_options_get_int(r->options, "start", 0);
751  count = ZOOM_options_get_int(r->options, "count", 0);
752  {
753  /* If "presentChunk" is defined use that; otherwise "step" */
754  const char *cp = ZOOM_options_get(r->options, "presentChunk");
756  (cp != 0 ? "presentChunk": "step"), 0);
757  }
758  r->piggyback = ZOOM_options_get_bool(r->options, "piggyback", 1);
759  r->setname = odr_strdup_null(r->odr,
760  ZOOM_options_get(r->options, "setname"));
761  r->databaseNames = ZOOM_connection_get_databases(c, c->options,
762  &r->num_databaseNames,
763  r->odr);
764  r->connection = c;
765  r->next = c->resultsets;
766  c->resultsets = r;
767 
769 
770  if (c->host_port && c->proto == PROTO_HTTP)
771  {
772  if (!c->cs)
773  {
774  yaz_log(c->log_details, "ZOOM_connection_search: no comstack");
776  }
777  else
778  {
779  yaz_log(c->log_details, "ZOOM_connection_search: reconnect");
780  c->reconnect_ok = 1;
781  }
782  }
783 
785  task->u.search.resultset = r;
786  task->u.search.start = start;
787  task->u.search.count = count;
788 
789  syntax = ZOOM_options_get(r->options, "preferredRecordSyntax");
790  task->u.search.syntax = syntax ? xstrdup(syntax) : 0;
791  elementSetName = ZOOM_options_get(r->options, "elementSetName");
792  task->u.search.elementSetName = elementSetName ?
793  xstrdup(elementSetName) : 0;
794  schema = ZOOM_options_get(r->options, "schema");
795  task->u.search.schema = schema ? xstrdup(schema) : 0;
796 
798 
799  if (!c->async)
800  {
801  while (ZOOM_event(1, &c))
802  ;
803  }
804  return r;
805 }
806 
807 ZOOM_API(void)
809  const char *sort_type, const char *sort_spec)
810 {
811  (void) ZOOM_resultset_sort1(r, sort_type, sort_spec);
812 }
813 
814 ZOOM_API(int)
816  const char *sort_type, const char *sort_spec)
817 {
818  ZOOM_connection c = r->connection;
819  ZOOM_task task;
820  ZOOM_query newq;
821 
822  newq = ZOOM_query_create();
823  if (ZOOM_query_sortby(newq, sort_spec) < 0)
824  return -1;
825 
826  yaz_log(c->log_api, "%p ZOOM_resultset_sort r=%p sort_type=%s sort_spec=%s",
827  r, r, sort_type, sort_spec);
828  if (!c)
829  return 0;
830 
831  if (c->host_port && c->proto == PROTO_HTTP)
832  {
833  if (!c->cs)
834  {
835  yaz_log(c->log_details, "%p ZOOM_resultset_sort: no comstack", r);
837  }
838  else
839  {
840  yaz_log(c->log_details, "%p ZOOM_resultset_sort: prepare reconnect",
841  r);
842  c->reconnect_ok = 1;
843  }
844  }
845 
848  task->u.sort.resultset = r;
849  task->u.sort.q = newq;
850 
852 
853  if (!c->async)
854  {
855  while (ZOOM_event(1, &c))
856  ;
857  }
858 
859  return 0;
860 }
861 
862 ZOOM_API(void)
864 {
866 }
867 
869 {
870  if (!r)
871  return;
873  (r->refcount)--;
874  yaz_log(log_details0, "%p ZOOM_resultset_destroy r=%p count=%d",
875  r, r, r->refcount);
876  if (r->refcount == 0)
877  {
879 
880  yaz_log(log_details0, "%p ZOOM_connection resultset_destroy: Deleting resultset (%p) ", r->connection, r);
885  odr_destroy(r->odr);
887 #if SHPTR
889 #endif
890  wrbuf_destroy(r->mc_key);
891  resultset_use(-1);
892  xfree(r);
893  }
894  else
896 }
897 
898 ZOOM_API(size_t)
900 {
901  return r->size;
902 }
903 
905 {
906  ZOOM_Event event;
907 
908  if (!c->reconnect_ok)
909  return 0;
911  c->reconnect_ok = 0;
912  c->tasks->running = 0;
914 
916  ZOOM_connection_put_event(c, event);
917 
918  return 1;
919 }
920 
922  int force_sync, int start, int count)
923 {
924  ZOOM_task task;
925  ZOOM_connection c;
926  const char *cp;
927  const char *syntax, *elementSetName;
928 
929  if (!r)
930  return;
931  yaz_log(log_details0, "%p ZOOM_resultset_retrieve force_sync=%d start=%d"
932  " count=%d", r, force_sync, start, count);
933  c = r->connection;
934  if (!c)
935  return;
936 
937  if (c->host_port && c->proto == PROTO_HTTP)
938  {
939  if (!c->cs)
940  {
941  yaz_log(log_details0, "%p ZOOM_resultset_retrieve: no comstack", r);
943  }
944  else
945  {
946  yaz_log(log_details0, "%p ZOOM_resultset_retrieve: prepare "
947  "reconnect", r);
948  c->reconnect_ok = 1;
949  }
950  }
952  task->u.search.resultset = r;
953  task->u.search.start = start;
954  task->u.search.count = count;
955 
956  syntax = ZOOM_options_get(r->options, "preferredRecordSyntax");
957  task->u.search.syntax = syntax ? xstrdup(syntax) : 0;
958  elementSetName = ZOOM_options_get(r->options, "elementSetName");
959  task->u.search.elementSetName = elementSetName
960  ? xstrdup(elementSetName) : 0;
961 
962  cp = ZOOM_options_get(r->options, "schema");
963  task->u.search.schema = cp ? xstrdup(cp) : 0;
964 
966 
967  if (!r->connection->async || force_sync)
968  while (r->connection && ZOOM_event(1, &r->connection))
969  ;
970 }
971 
972 ZOOM_API(void)
974  size_t start, size_t count)
975 {
976  int force_present = 0;
977 
978  if (!r)
979  return ;
980  yaz_log(log_api0, "%p ZOOM_resultset_records r=%p start=%ld count=%ld",
981  r, r, (long) start, (long) count);
982  if (count && recs)
983  force_present = 1;
984  ZOOM_resultset_retrieve(r, force_present, start, count);
985  if (force_present)
986  {
987  size_t i;
988  for (i = 0; i< count; i++)
989  recs[i] = ZOOM_resultset_record_immediate(r, i+start);
990  }
991 }
992 
993 ZOOM_API(size_t)
995 {
996  return r->num_res_facets;
997 }
998 
1001 {
1002  int num = r->num_res_facets;
1003  ZOOM_facet_field *facets = r->res_facets;
1004  int i;
1005  for (i = 0; i < num; i++)
1006  if (!strcmp(facets[i]->facet_name, name))
1007  return facets[i];
1008  return 0;
1009 }
1010 
1013 {
1014  int num = r->num_res_facets;
1015  ZOOM_facet_field *facets = r->res_facets;
1016  if (idx >= 0 && idx < num)
1017  return facets[idx];
1018  return 0;
1019 }
1020 
1023 {
1024  return r->res_facets;
1025 }
1026 
1027 ZOOM_API(const char**)
1029 {
1030  return (const char **) r->facets_names;
1031 }
1032 
1033 ZOOM_API(const char*)
1035 {
1036  return field->facet_name;
1037 }
1038 
1039 ZOOM_API(size_t)
1041 {
1042  return field->num_terms;
1043 }
1044 
1045 ZOOM_API(const char*)
1046  ZOOM_facet_field_get_term(ZOOM_facet_field field, size_t idx, int *freq)
1047 {
1048  *freq = field->facet_terms[idx].frequency;
1049  return field->facet_terms[idx].term;
1050 }
1051 
1052 
1054 {
1055  char *cert_buf;
1056  int cert_len;
1057 
1058  if (cs_get_peer_certificate_x509(c->cs, &cert_buf, &cert_len))
1059  {
1060  ZOOM_connection_option_setl(c, "sslPeerCert",
1061  cert_buf, cert_len);
1062  xfree(cert_buf);
1063  }
1064 }
1065 
1067  const char *logical_url);
1068 
1070 {
1071  return do_connect_host(c, c->host_port);
1072 }
1073 
1074 static zoom_ret do_connect_host(ZOOM_connection c, const char *logical_url)
1075 {
1076  void *add;
1077 
1078  if (c->cs)
1079  cs_close(c->cs);
1080  c->cs = cs_create_host2(logical_url, CS_FLAGS_DNS_NO_BLOCK, &add,
1081  c->tproxy ? c->tproxy : c->proxy,
1082  &c->proxy_mode);
1083  if (!c->proxy)
1084  c->proxy_mode = 0;
1085 
1086  if (c->cs && c->cs->protocol == PROTO_HTTP)
1087  {
1088 #if YAZ_HAVE_XML2
1089  c->proto = PROTO_HTTP;
1090 #else
1093  return zoom_complete;
1094 #endif
1095  }
1096  if (c->cs)
1097  {
1098  int ret = cs_connect(c->cs, add);
1099  if (ret == 0)
1100  {
1102  ZOOM_connection_put_event(c, event);
1103  get_cert(c);
1104  if (c->proto == PROTO_Z3950)
1106  else
1107  {
1108  /* no init request for SRW .. */
1109  assert(c->tasks->which == ZOOM_TASK_CONNECT);
1112 
1113  if (c->cs && c->location)
1115  else
1117  }
1118  c->state = STATE_ESTABLISHED;
1119  return zoom_pending;
1120  }
1121  else if (ret > 0)
1122  {
1123  int mask = ZOOM_SELECT_EXCEPT;
1124  if (c->cs->io_pending & CS_WANT_WRITE)
1126  if (c->cs->io_pending & CS_WANT_READ)
1129  c->state = STATE_CONNECTING;
1130  return zoom_pending;
1131  }
1132  }
1133  c->state = STATE_IDLE;
1134  ZOOM_set_error(c, ZOOM_ERROR_CONNECT, logical_url);
1135  return zoom_complete;
1136 }
1137 
1138 /* returns 1 if PDU was sent OK (still pending )
1139  0 if PDU was not sent OK (nothing to wait for)
1140 */
1141 
1144 {
1145  const char *syntax =
1146  ZOOM_options_get(s->options, "preferredRecordSyntax");
1147  const char *elementSetName =
1148  ZOOM_options_get(s->options, "elementSetName");
1149  const char *schema =
1150  ZOOM_options_get(s->options, "schema");
1151 
1152  return ZOOM_record_cache_lookup_i(s, pos, syntax, elementSetName, schema);
1153 }
1154 
1157 {
1159 
1160  if (!rec)
1161  {
1162  /*
1163  * MIKE: I think force_sync should always be zero, but I don't
1164  * want to make this change until I get the go-ahead from
1165  * Adam, in case something depends on the old synchronous
1166  * behaviour.
1167  */
1168  int force_sync = 1;
1169  if (getenv("ZOOM_RECORD_NO_FORCE_SYNC")) force_sync = 0;
1170  ZOOM_resultset_retrieve(r, force_sync, pos, 1);
1171  rec = ZOOM_resultset_record_immediate(r, pos);
1172  }
1173  return rec;
1174 }
1175 
1178 {
1179  ZOOM_scanset s;
1181 
1182  ZOOM_query_prefix(q, start);
1183 
1184  s = ZOOM_connection_scan1(c, q);
1185  ZOOM_query_destroy(q);
1186  return s;
1187 
1188 }
1189 
1192 {
1193  ZOOM_scanset scan = 0;
1194  Z_Query *z_query = ZOOM_query_get_Z_Query(q);
1195 
1196  if (!z_query)
1197  return 0;
1198  scan = (ZOOM_scanset) xmalloc(sizeof(*scan));
1199  scan->connection = c;
1200  scan->odr = odr_createmem(ODR_DECODE);
1201  scan->options = ZOOM_options_create_with_parent(c->options);
1202  scan->refcount = 1;
1203  scan->scan_response = 0;
1204  scan->srw_scan_response = 0;
1205 
1206  scan->query = q;
1207  ZOOM_query_addref(q);
1208  scan->databaseNames = ZOOM_connection_get_databases(c, c->options,
1209  &scan->num_databaseNames,
1210  scan->odr);
1211 
1212  if (1)
1213  {
1215  task->u.scan.scan = scan;
1216 
1217  (scan->refcount)++;
1218  if (!c->async)
1219  {
1220  while (ZOOM_event(1, &c))
1221  ;
1222  }
1223  }
1224  return scan;
1225 }
1226 
1227 ZOOM_API(void)
1229 {
1230  if (!scan)
1231  return;
1232  (scan->refcount)--;
1233  if (scan->refcount == 0)
1234  {
1235  ZOOM_query_destroy(scan->query);
1236 
1237  odr_destroy(scan->odr);
1238 
1239  ZOOM_options_destroy(scan->options);
1240  xfree(scan);
1241  }
1242 }
1243 
1245 {
1246  ZOOM_Event event;
1247 
1248  yaz_log(c->log_details, "%p send_package", c);
1249  if (!c->tasks)
1250  return zoom_complete;
1251  assert (c->tasks->which == ZOOM_TASK_PACKAGE);
1252 
1254  ZOOM_connection_put_event(c, event);
1255 
1256  c->buf_out = c->tasks->u.package->buf_out;
1257  c->len_out = c->tasks->u.package->len_out;
1258 
1259  return ZOOM_send_buf(c);
1260 }
1261 
1262 ZOOM_API(size_t)
1264 {
1265  if (!scan)
1266  return 0;
1267 
1268  if (scan->scan_response && scan->scan_response->entries)
1269  return scan->scan_response->entries->num_entries;
1270  else if (scan->srw_scan_response)
1271  return scan->srw_scan_response->num_terms;
1272  return 0;
1273 }
1274 
1275 static void ZOOM_scanset_term_x(ZOOM_scanset scan, size_t pos,
1276  size_t *occ,
1277  const char **value_term, size_t *value_len,
1278  const char **disp_term, size_t *disp_len)
1279 {
1280  size_t noent = ZOOM_scanset_size(scan);
1281 
1282  *value_term = 0;
1283  *value_len = 0;
1284 
1285  *disp_term = 0;
1286  *disp_len = 0;
1287 
1288  *occ = 0;
1289  if (pos >= noent)
1290  return;
1291  if (scan->scan_response)
1292  {
1293  Z_ScanResponse *res = scan->scan_response;
1294  if (res->entries->entries[pos]->which == Z_Entry_termInfo)
1295  {
1296  Z_TermInfo *t = res->entries->entries[pos]->u.termInfo;
1297 
1298  *value_term = (const char *) t->term->u.general->buf;
1299  *value_len = t->term->u.general->len;
1300  if (t->displayTerm)
1301  {
1302  *disp_term = t->displayTerm;
1303  *disp_len = strlen(*disp_term);
1304  }
1305  else if (t->term->which == Z_Term_general)
1306  {
1307  *disp_term = (const char *) t->term->u.general->buf;
1308  *disp_len = t->term->u.general->len;
1309  }
1310  *occ = t->globalOccurrences ? *t->globalOccurrences : 0;
1311  }
1312  }
1313  if (scan->srw_scan_response)
1314  {
1316  Z_SRW_scanTerm *t = res->terms + pos;
1317  if (t)
1318  {
1319  *value_term = t->value;
1320  *value_len = strlen(*value_term);
1321 
1322  if (t->displayTerm)
1323  *disp_term = t->displayTerm;
1324  else
1325  *disp_term = t->value;
1326  *disp_len = strlen(*disp_term);
1327  *occ = t->numberOfRecords ? *t->numberOfRecords : 0;
1328  }
1329  }
1330 }
1331 
1332 ZOOM_API(const char *)
1334  size_t *occ, size_t *len)
1335 {
1336  const char *value_term = 0;
1337  size_t value_len = 0;
1338  const char *disp_term = 0;
1339  size_t disp_len = 0;
1340 
1341  ZOOM_scanset_term_x(scan, pos, occ, &value_term, &value_len,
1342  &disp_term, &disp_len);
1343 
1344  *len = value_len;
1345  return value_term;
1346 }
1347 
1348 ZOOM_API(const char *)
1350  size_t *occ, size_t *len)
1351 {
1352  const char *value_term = 0;
1353  size_t value_len = 0;
1354  const char *disp_term = 0;
1355  size_t disp_len = 0;
1356 
1357  ZOOM_scanset_term_x(scan, pos, occ, &value_term, &value_len,
1358  &disp_term, &disp_len);
1359 
1360  *len = disp_len;
1361  return disp_term;
1362 }
1363 
1364 ZOOM_API(const char *)
1365  ZOOM_scanset_option_get(ZOOM_scanset scan, const char *key)
1366 {
1367  return ZOOM_options_get(scan->options, key);
1368 }
1369 
1370 ZOOM_API(void)
1371  ZOOM_scanset_option_set(ZOOM_scanset scan, const char *key,
1372  const char *val)
1373 {
1374  ZOOM_options_set(scan->options, key, val);
1375 }
1376 
1377 
1380 {
1381  ZOOM_package p = (ZOOM_package) xmalloc(sizeof(*p));
1382 
1383  p->connection = c;
1386  p->refcount = 1;
1387  p->buf_out = 0;
1388  p->len_out = 0;
1389  return p;
1390 }
1391 
1392 ZOOM_API(void)
1394 {
1395  if (!p)
1396  return;
1397  (p->refcount)--;
1398  if (p->refcount == 0)
1399  {
1400  odr_destroy(p->odr_out);
1401  xfree(p->buf_out);
1402 
1403  ZOOM_options_destroy(p->options);
1404  xfree(p);
1405  }
1406 }
1407 
1408 ZOOM_API(const char *)
1410 {
1411  return ZOOM_options_get(p->options, key);
1412 }
1413 
1414 ZOOM_API(const char *)
1415  ZOOM_package_option_getl(ZOOM_package p, const char *key, int *lenp)
1416 {
1417  return ZOOM_options_getl(p->options, key, lenp);
1418 }
1419 
1420 ZOOM_API(void)
1422  const char *val)
1423 {
1424  ZOOM_options_set(p->options, key, val);
1425 }
1426 
1427 ZOOM_API(void)
1429  const char *val, int len)
1430 {
1431  ZOOM_options_setl(p->options, key, val, len);
1432 }
1433 
1434 ZOOM_API(int)
1436 {
1437  ZOOM_task task = c->tasks;
1438  zoom_ret ret = zoom_complete;
1439 
1440  if (!task)
1441  return 0;
1442  yaz_log(c->log_details, "%p ZOOM_connection_exec_task type=%d run=%d",
1443  c, task->which, task->running);
1444  if (c->error != ZOOM_ERROR_NONE)
1445  {
1446  yaz_log(c->log_details, "%p ZOOM_connection_exec_task "
1447  "removing tasks because of error = %d", c, c->error);
1449  return 0;
1450  }
1451  if (task->running)
1452  {
1453  yaz_log(c->log_details, "%p ZOOM_connection_exec_task "
1454  "task already running", c);
1455  return 0;
1456  }
1457  task->running = 1;
1458  ret = zoom_complete;
1459  if (c->cs || task->which == ZOOM_TASK_CONNECT)
1460  {
1461  switch (task->which)
1462  {
1463  case ZOOM_TASK_SEARCH:
1464  if (c->proto == PROTO_HTTP)
1466  else
1468  break;
1469  case ZOOM_TASK_CONNECT:
1470  ret = do_connect(c);
1471  break;
1472  case ZOOM_TASK_SCAN:
1473  if (c->proto == PROTO_HTTP)
1475  else
1477  break;
1478  case ZOOM_TASK_PACKAGE:
1479  ret = send_package(c);
1480  break;
1481  case ZOOM_TASK_SORT:
1482  c->tasks->u.sort.resultset->r_sort_spec =
1483  ZOOM_query_get_sortspec(c->tasks->u.sort.q);
1484  ret = send_Z3950_sort(c, c->tasks->u.sort.resultset);
1485  break;
1486  }
1487  }
1488  else
1489  {
1490  yaz_log(c->log_details, "%p ZOOM_connection_exec_task "
1491  "remove tasks because no connection exist", c);
1493  }
1494  if (ret == zoom_complete)
1495  {
1496  yaz_log(c->log_details, "%p ZOOM_connection_exec_task "
1497  "task removed (complete)", c);
1499  return 0;
1500  }
1501  yaz_log(c->log_details, "%p ZOOM_connection_exec_task "
1502  "task pending", c);
1503  return 1;
1504 }
1505 
1506 
1507 static zoom_ret send_HTTP_redirect(ZOOM_connection c, const char *uri)
1508 {
1509  Z_GDU *gdu = z_get_HTTP_Request_uri(c->odr_out, uri, 0, c->proxy ? 1 : 0);
1510 
1511  gdu->u.HTTP_Request->method = odr_strdup(c->odr_out, "GET");
1512  z_HTTP_header_add(c->odr_out, &gdu->u.HTTP_Request->headers, "Accept",
1513  "text/xml");
1515  if (c->user && c->password)
1516  {
1518  c->user, c->password);
1519  }
1520  xfree(c->location);
1521  c->location = 0;
1522  return ZOOM_send_GDU(c, gdu);
1523 }
1524 
1525 
1527 {
1528  ZOOM_Event event;
1529 
1530  int r = z_GDU(c->odr_out, &gdu, 0, 0);
1531  if (!r)
1532  return zoom_complete;
1533  if (c->odr_print)
1534  z_GDU(c->odr_print, &gdu, 0, 0);
1535  if (c->odr_save)
1536  z_GDU(c->odr_save, &gdu, 0, 0);
1537  c->buf_out = odr_getbuf(c->odr_out, &c->len_out, 0);
1538  odr_reset(c->odr_out);
1539 
1541  ZOOM_connection_put_event(c, event);
1542 
1543  return ZOOM_send_buf(c);
1544 }
1545 
1547  const char *addinfo, const char *addinfo2)
1548 {
1549  ZOOM_set_dset_error(c, error, "HTTP", addinfo, addinfo2);
1550 }
1551 
1552 #if YAZ_HAVE_XML2
1554 {
1555  zoom_ret cret = zoom_complete;
1556  int ret = -1;
1557  char *addinfo = 0;
1558  const char *connection_head = z_HTTP_header_lookup(hres->headers,
1559  "Connection");
1560  int must_close = 0;
1561  const char *location;
1562 
1564  yaz_log(c->log_details, "%p handle_http", c);
1565  if (!strcmp(hres->version, "1.0"))
1566  {
1567  /* HTTP 1.0: only if Keep-Alive we stay alive.. */
1568  if (!connection_head || strcmp(connection_head, "Keep-Alive"))
1569  must_close = 1;
1570  }
1571  else
1572  {
1573  /* HTTP 1.1: only if no close we stay alive.. */
1574  if (connection_head && !strcmp(connection_head, "close"))
1575  must_close = 1;
1576  }
1577  yaz_cookies_response(c->cookies, hres);
1578  if ((hres->code == 301 || hres->code == 302) && c->sru_mode == zoom_sru_get
1579  && (location = z_HTTP_header_lookup(hres->headers, "Location")))
1580  {
1581  c->no_redirects++;
1582  if (c->no_redirects > 10)
1583  {
1584  ZOOM_set_HTTP_error(c, hres->code, 0, 0);
1585  c->no_redirects = 0;
1587  }
1588  else
1589  {
1590  /* since redirect may change host we just reconnect. A smarter
1591  implementation might check whether it's the same server */
1592 
1593  int host_change = 0;
1594  location = yaz_check_location(c->odr_in, c->host_port,
1595  location, &host_change);
1596  xfree(c->location);
1597  c->location = xstrdup(location);
1598  do_connect_host(c, location);
1599  return;
1600  }
1601  }
1602  else
1603  {
1604  ret = ZOOM_handle_sru(c, hres, &cret, &addinfo);
1605  if (ret == 0)
1606  {
1607  if (c->no_redirects) /* end of redirect. change hosts again */
1609  }
1610  c->no_redirects = 0;
1611  }
1612  if (ret)
1613  {
1614  if (hres->code != 200)
1615  ZOOM_set_HTTP_error(c, hres->code, 0, 0);
1616  else
1617  {
1618  yaz_log(YLOG_LOG, "set error... addinfo=%s", addinfo ?
1619  addinfo : "NULL");
1620  ZOOM_set_error(c, ZOOM_ERROR_DECODE, addinfo);
1621  }
1623  }
1624  if (cret == zoom_complete)
1625  {
1626  yaz_log(c->log_details, "removing tasks in handle_http");
1628  }
1629  if (must_close)
1630  {
1632  if (c->tasks)
1633  {
1634  c->tasks->running = 0;
1636  c->reconnect_ok = 0;
1637  }
1638  }
1639  else
1640  c->reconnect_ok = 1; /* if the server closes anyway */
1641 }
1642 #endif
1643 
1645 {
1646  int r, more;
1647  ZOOM_Event event;
1648 
1650  ZOOM_connection_put_event(c, event);
1651 
1652  r = cs_get(c->cs, &c->buf_in, &c->len_in);
1653  more = cs_more(c->cs);
1654  yaz_log(c->log_details, "%p do_read len=%d more=%d", c, r, more);
1655  if (r == 1)
1656  return 0;
1657  if (r <= 0)
1658  {
1659  if (!ZOOM_test_reconnect(c))
1660  {
1663  }
1664  }
1665  else
1666  {
1667  Z_GDU *gdu;
1668  ZOOM_Event event;
1669 
1670  odr_reset(c->odr_in);
1671  odr_setbuf(c->odr_in, c->buf_in, r, 0);
1673  ZOOM_connection_put_event(c, event);
1674 
1675  if (!z_GDU(c->odr_in, &gdu, 0, 0))
1676  {
1677  /* even on failures we try to re-connect (HTTP) */
1678  if (!ZOOM_test_reconnect(c))
1679  {
1680  int x;
1681  int err = odr_geterrorx(c->odr_in, &x);
1682  char msg[100];
1683  const char *element = odr_getelement(c->odr_in);
1684  yaz_snprintf(msg, sizeof(msg),
1685  "ODR code %d:%d element=%s offset=%d",
1686  err, x, element ? element : "<unknown>",
1687  odr_offset(c->odr_in));
1689  if (c->log_api)
1690  {
1691  FILE *ber_file = yaz_log_file();
1692  if (ber_file)
1693  odr_dumpBER(ber_file, c->buf_in, r);
1694  }
1696  }
1697  }
1698  else
1699  {
1700  if (c->odr_print)
1701  z_GDU(c->odr_print, &gdu, 0, 0);
1702  if (c->odr_save)
1703  z_GDU(c->odr_save, &gdu, 0, 0);
1704  if (gdu->which == Z_GDU_Z3950)
1705  ZOOM_handle_Z3950_apdu(c, gdu->u.z3950);
1706  else if (gdu->which == Z_GDU_HTTP_Response)
1707  {
1708 #if YAZ_HAVE_XML2
1709  handle_http(c, gdu->u.HTTP_Response);
1710 #else
1713 #endif
1714  }
1715  }
1716  }
1717  return 1;
1718 }
1719 
1720 static zoom_ret do_write_ex(ZOOM_connection c, char *buf_out, int len_out)
1721 {
1722  int r;
1723  ZOOM_Event event;
1724 
1726  ZOOM_connection_put_event(c, event);
1727 
1728  yaz_log(c->log_details, "%p do_write_ex len=%d", c, len_out);
1729  if ((r = cs_put(c->cs, buf_out, len_out)) < 0)
1730  {
1731  yaz_log(c->log_details, "%p do_write_ex write failed", c);
1732  if (ZOOM_test_reconnect(c))
1733  {
1734  return zoom_pending;
1735  }
1736  if (c->state == STATE_CONNECTING)
1738  else
1741  return zoom_complete;
1742  }
1743  else if (r == 1)
1744  {
1745  int mask = ZOOM_SELECT_EXCEPT;
1746  if (c->cs->io_pending & CS_WANT_WRITE)
1748  if (c->cs->io_pending & CS_WANT_READ)
1751  yaz_log(c->log_details, "%p do_write_ex write incomplete mask=%d",
1752  c, c->mask);
1753  }
1754  else
1755  {
1757  yaz_log(c->log_details, "%p do_write_ex write complete mask=%d",
1758  c, c->mask);
1759  }
1760  return zoom_pending;
1761 }
1762 
1764 {
1765  return do_write_ex(c, c->buf_out, c->len_out);
1766 }
1767 
1768 
1769 ZOOM_API(const char *)
1771 {
1772  if (!strcmp(key, "APDU"))
1773  {
1774  return c->saveAPDU_wrbuf ? wrbuf_cstr(c->saveAPDU_wrbuf) : "";
1775  }
1776  else
1777  return ZOOM_options_get(c->options, key);
1778 }
1779 
1780 ZOOM_API(const char *)
1781  ZOOM_connection_option_getl(ZOOM_connection c, const char *key, int *lenp)
1782 {
1783  if (!strcmp(key, "APDU"))
1784  {
1785  if (c->saveAPDU_wrbuf)
1786  {
1787  *lenp = wrbuf_len(c->saveAPDU_wrbuf);
1788  return wrbuf_cstr(c->saveAPDU_wrbuf);
1789  }
1790  else
1791  {
1792  *lenp = 0;
1793  return "";
1794  }
1795  }
1796  else
1797  return ZOOM_options_getl(c->options, key, lenp);
1798 }
1799 
1800 ZOOM_API(void)
1802  const char *val)
1803 {
1804  if (!strcmp(key, "saveAPDU"))
1805  {
1806  if (val && strcmp(val, "0"))
1807  {
1808  if (!c->saveAPDU_wrbuf)
1809  c->saveAPDU_wrbuf = wrbuf_alloc();
1810  else
1811  wrbuf_rewind(c->saveAPDU_wrbuf);
1812  }
1813  else
1814  {
1815  wrbuf_destroy(c->saveAPDU_wrbuf);
1816  c->saveAPDU_wrbuf = 0;
1817  }
1818  ZOOM_connection_save_apdu_wrbuf(c, c->saveAPDU_wrbuf);
1819  }
1820  else
1821  ZOOM_options_set(c->options, key, val);
1822 }
1823 
1824 ZOOM_API(void)
1826  const char *val, int len)
1827 {
1828  ZOOM_options_setl(c->options, key, val, len);
1829 }
1830 
1831 ZOOM_API(const char *)
1833 {
1834  return ZOOM_options_get(r->options, key);
1835 }
1836 
1837 ZOOM_API(void)
1839  const char *val)
1840 {
1841  ZOOM_options_set(r->options, key, val);
1842 }
1843 
1844 
1845 ZOOM_API(int)
1847 {
1848  return ZOOM_connection_error(c, 0, 0);
1849 }
1850 
1851 ZOOM_API(const char *)
1853 {
1854  const char *msg;
1855  ZOOM_connection_error(c, &msg, 0);
1856  return msg;
1857 }
1858 
1859 ZOOM_API(const char *)
1861 {
1862  const char *addinfo;
1863  ZOOM_connection_error(c, 0, &addinfo);
1864  return addinfo;
1865 }
1866 
1867 ZOOM_API(const char *)
1869 {
1870  const char *diagset;
1871  ZOOM_connection_error_x(c, 0, 0, &diagset);
1872  return diagset;
1873 }
1874 
1875 ZOOM_API(const char *)
1876  ZOOM_diag_str(int error)
1877 {
1878  switch (error)
1879  {
1880  case ZOOM_ERROR_NONE:
1881  return "No error";
1882  case ZOOM_ERROR_CONNECT:
1883  return "Connect failed";
1884  case ZOOM_ERROR_MEMORY:
1885  return "Out of memory";
1886  case ZOOM_ERROR_ENCODE:
1887  return "Encoding failed";
1888  case ZOOM_ERROR_DECODE:
1889  return "Decoding failed";
1891  return "Connection lost";
1892  case ZOOM_ERROR_INIT:
1893  return "Init rejected";
1894  case ZOOM_ERROR_INTERNAL:
1895  return "Internal failure";
1896  case ZOOM_ERROR_TIMEOUT:
1897  return "Timeout";
1899  return "Unsupported protocol";
1901  return "Unsupported query type";
1903  return "Invalid query";
1904  case ZOOM_ERROR_CQL_PARSE:
1905  return "CQL parsing error";
1907  return "CQL transformation error";
1908  case ZOOM_ERROR_CCL_CONFIG:
1909  return "CCL configuration error";
1910  case ZOOM_ERROR_CCL_PARSE:
1911  return "CCL parsing error";
1913  return "Extended Service. invalid action";
1915  return "Extended Service. invalid version";
1917  return "Extended Service. invalid syntax";
1918  case ZOOM_ERROR_MEMCACHED:
1919  return "Memcached";
1920  default:
1921  return diagbib1_str(error);
1922  }
1923 }
1924 
1925 ZOOM_API(int)
1927  const char **addinfo, const char **diagset)
1928 {
1929  int error = c->error;
1930  if (cp)
1931  {
1932  if (!c->diagset || !strcmp(c->diagset, "ZOOM"))
1933  *cp = ZOOM_diag_str(error);
1934  else if (!strcmp(c->diagset, "HTTP"))
1935  *cp = z_HTTP_errmsg(c->error);
1936  else if (!strcmp(c->diagset, "Bib-1"))
1937  *cp = ZOOM_diag_str(error);
1938  else if (!strcmp(c->diagset, "info:srw/diagnostic/1"))
1939  *cp = yaz_diag_srw_str(c->error);
1940  else
1941  *cp = "Unknown error and diagnostic set";
1942  }
1943  if (addinfo)
1944  *addinfo = c->addinfo ? c->addinfo : "";
1945  if (diagset)
1946  *diagset = c->diagset ? c->diagset : "";
1947  return c->error;
1948 }
1949 
1950 ZOOM_API(int)
1952  const char **addinfo)
1953 {
1954  return ZOOM_connection_error_x(c, cp, addinfo, 0);
1955 }
1956 
1958 {
1959  ZOOM_Event event = 0;
1960  int r = cs_look(c->cs);
1961  yaz_log(c->log_details, "%p ZOOM_connection_do_io mask=%d cs_look=%d",
1962  c, mask, r);
1963 
1964  if (r == CS_NONE)
1965  {
1969  ZOOM_connection_put_event(c, event);
1970  }
1971  else if (r == CS_CONNECT)
1972  {
1973  int ret = cs_rcvconnect(c->cs);
1974  yaz_log(c->log_details, "%p ZOOM_connection_do_io "
1975  "cs_rcvconnect returned %d", c, ret);
1976  if (ret == 1)
1977  {
1978  int mask = ZOOM_SELECT_EXCEPT;
1979  if (c->cs->io_pending & CS_WANT_WRITE)
1981  if (c->cs->io_pending & CS_WANT_READ)
1985  ZOOM_connection_put_event(c, event);
1986  }
1987  else if (ret == 0)
1988  {
1990  ZOOM_connection_put_event(c, event);
1991  get_cert(c);
1992  if (c->proto == PROTO_Z3950)
1994  else
1995  {
1996  /* no init request for SRW .. */
1997  if (c->tasks->which == ZOOM_TASK_CONNECT)
1998  {
2001  }
2002  if (c->cs && c->location)
2004  else
2006  }
2007  if (c->cs && cs_look(c->cs) == CS_DATA)
2008  c->state = STATE_ESTABLISHED;
2009  }
2010  else
2011  {
2014  }
2015  }
2016  else
2017  {
2018  if (mask & ZOOM_SELECT_EXCEPT)
2019  {
2020  if (!ZOOM_test_reconnect(c))
2021  {
2024  }
2025  return;
2026  }
2027  if (mask & ZOOM_SELECT_READ)
2028  do_read(c);
2029  if (c->cs && (mask & ZOOM_SELECT_WRITE))
2030  ZOOM_send_buf(c);
2031  }
2032 }
2033 
2034 ZOOM_API(int)
2036 {
2037  if (!cs)
2038  return ZOOM_EVENT_NONE;
2039  return cs->last_event;
2040 }
2041 
2042 
2044 {
2045  if (c->mask)
2046  {
2048  /* timeout and this connection was waiting */
2051  ZOOM_connection_put_event(c, event);
2052  }
2053  return 0;
2054 }
2055 
2056 ZOOM_API(int)
2058 {
2059  ZOOM_Event event;
2060  if (!c)
2061  return 0;
2062 
2063  event = ZOOM_connection_get_event(c);
2064  if (event)
2065  {
2066  ZOOM_Event_destroy(event);
2067  return 1;
2068  }
2070  event = ZOOM_connection_get_event(c);
2071  if (event)
2072  {
2073  ZOOM_Event_destroy(event);
2074  return 1;
2075  }
2076  return 0;
2077 }
2078 
2079 ZOOM_API(int)
2081 {
2082  int i;
2083 
2084  yaz_log(log_details0, "ZOOM_process_event(no=%d,cs=%p)", no, cs);
2085 
2086  for (i = 0; i<no; i++)
2087  {
2088  ZOOM_connection c = cs[i];
2089 
2090  if (c && ZOOM_connection_process(c))
2091  return i+1;
2092  }
2093  return 0;
2094 }
2095 
2097 {
2098  if (c->mask && mask)
2100  return 0;
2101 }
2102 
2104 {
2105  if (c->cs)
2106  return cs_fileno(c->cs);
2107  return -1;
2108 }
2109 
2111 {
2112  c->mask = mask;
2113  if (!c->cs)
2114  return -1;
2115  return 0;
2116 }
2117 
2119 {
2120  if (c->cs)
2121  return c->mask;
2122  return 0;
2123 }
2124 
2126 {
2127  return ZOOM_options_get_int(c->options, "timeout", 30);
2128 }
2129 
2131 {
2132  if (c->cs)
2133  cs_close(c->cs);
2134  c->cs = 0;
2136  c->state = STATE_IDLE;
2137 }
2138 
2139 /*
2140  * Local variables:
2141  * c-basic-offset: 4
2142  * c-file-style: "Stroustrup"
2143  * indent-tabs-mode: nil
2144  * End:
2145  * vim: shiftwidth=4 tabstop=8 expandtab
2146  */
2147 
Header for Z39.50 Charset negotiation utilities.
void cs_get_host_args(const char *type_and_host, const char **args)
Definition: comstack.c:48
int cs_look(COMSTACK cs)
Definition: comstack.c:257
COMSTACK cs_create_host2(const char *vhost, int blocking, void **vp, const char *proxy_host, int *proxy_mode)
Definition: comstack.c:179
#define cs_close(handle)
Definition: comstack.h:99
#define cs_connect(handle, address)
Definition: comstack.h:93
#define CS_DATA
Definition: comstack.h:69
#define cs_put(handle, buf, size)
Definition: comstack.h:90
#define cs_more(handle)
Definition: comstack.h:92
#define CS_WANT_READ
Definition: comstack.h:114
#define CS_NONE
Definition: comstack.h:65
#define CS_CONNECT
Definition: comstack.h:66
#define cs_get(handle, buf, size)
Definition: comstack.h:91
#define cs_fileno(handle)
Definition: comstack.h:104
#define CS_FLAGS_DNS_NO_BLOCK
Definition: comstack.h:167
#define CS_WANT_WRITE
Definition: comstack.h:115
#define cs_rcvconnect(handle)
Definition: comstack.h:94
void yaz_cookies_destroy(yaz_cookies_t yc)
Definition: cookie.c:35
yaz_cookies_t yaz_cookies_create(void)
Definition: cookie.c:28
void yaz_cookies_request(yaz_cookies_t yc, ODR odr, Z_HTTP_Request *req)
Definition: cookie.c:98
void yaz_cookies_response(yaz_cookies_t yc, Z_HTTP_Response *res)
Definition: cookie.c:60
const char * diagbib1_str(int code)
Definition: diagbib1.c:192
Diagnostics: Generated by csvtodiag.tcl from ./bib1.csv.
const char * yaz_diag_srw_str(int code)
Definition: diagsrw.c:110
int odr_dumpBER(FILE *f, const char *buf, int len)
Definition: dumpber.c:129
Header for errno utilities.
static int log_level_initialized
Definition: eventl.c:40
Header for the facet utilities.
const char * z_HTTP_errmsg(int code)
Definition: http.c:389
const char * z_HTTP_header_lookup(const Z_HTTP_Header *hp, const char *n)
Definition: http.c:233
Z_GDU * z_get_HTTP_Request_uri(ODR odr, const char *uri, const char *args, int use_full_uri)
Definition: http.c:291
void z_HTTP_header_add_basic_auth(ODR o, Z_HTTP_Header **hp, const char *username, const char *password)
Definition: http.c:168
const char * yaz_check_location(ODR odr, const char *uri, const char *location, int *host_change)
Definition: http.c:659
void z_HTTP_header_add(ODR o, Z_HTTP_Header **hp, const char *n, const char *v)
Definition: http.c:189
char * name
Definition: initopt.c:18
FILE * yaz_log_file(void)
returns FILE handle for log or NULL if no file is in use
Definition: log.c:138
enum l_file_type type
Definition: log.c:47
int mask
Definition: log.c:83
void yaz_log(int level, const char *fmt,...)
Writes log message.
Definition: log.c:487
int yaz_log_module_level(const char *name)
returns level for module
Definition: log.c:586
Logging utility.
#define YLOG_LOG
log level: log (regular)
Definition: log.h:48
int yaz_matchstr(const char *s1, const char *s2)
match strings - independent of case and '-'
Definition: matchstr.c:42
void yaz_mutex_leave(YAZ_MUTEX p)
leave critical section / AKA unlock
Definition: mutex.c:123
void yaz_mutex_enter(YAZ_MUTEX p)
enter critical section / AKA lock
Definition: mutex.c:72
void yaz_mutex_create(YAZ_MUTEX *p)
create MUTEX
Definition: mutex.c:43
void yaz_mutex_destroy(YAZ_MUTEX *p)
destroy MUTEX
Definition: mutex.c:141
void nmem_strsplit(NMEM nmem, const char *delim, const char *dstr, char ***darray, int *num)
allocates sub strings out of string using certain delimitors
Definition: nmemsdup.c:61
void odr_setprint_noclose(ODR o, FILE *file)
Definition: odr.c:169
int odr_geterrorx(ODR o, int *x)
Definition: odr.c:83
int odr_offset(ODR o)
Definition: odr.c:285
ODR odr_createmem(int direction)
Definition: odr.c:200
void odr_setbuf(ODR o, char *buf, int len, int can_grow)
Definition: odr.c:267
void odr_setprint(ODR o, FILE *file)
Definition: odr.c:164
void odr_set_stream(ODR o, void *handle, void(*stream_write)(ODR o, void *handle, int type, const char *buf, int len), void(*stream_close)(void *handle))
Definition: odr.c:174
char * odr_getbuf(ODR o, int *len, int *size)
Definition: odr.c:277
const char * odr_getelement(ODR o)
Definition: odr.c:90
void odr_destroy(ODR o)
Definition: odr.c:253
void odr_reset(ODR o)
Definition: odr.c:226
#define ODR_DECODE
Definition: odr.h:95
#define odr_getmem(o)
Definition: odr.h:216
#define ODR_PRINT
Definition: odr.h:97
#define ODR_ENCODE
Definition: odr.h:96
char * odr_strdup_null(ODR o, const char *str)
Definition: odr_mem.c:41
char * odr_strdup(ODR o, const char *str)
Definition: odr_mem.c:36
@ PROTO_HTTP
Definition: oid_util.h:48
@ PROTO_Z3950
Definition: oid_util.h:47
int options(const char *desc, char **argv, int argc, char **arg)
command-line options parsing for main
Definition: options.c:21
Header for Z39.50 OtherInfo utilities.
Query to WRBUF (to strings)
Shared pointer macros.
#define YAZ_SHPTR_INIT(p, n)
Definition: shptr.h:50
#define YAZ_SHPTR_DEC(p, destroy)
Definition: shptr.h:64
#define YAZ_SHPTR_TYPE(type)
Definition: shptr.h:41
void yaz_snprintf(char *buf, size_t size, const char *fmt,...)
Definition: snprintf.c:31
Header for config file reading utilities.
char * diagset
Definition: zoom-p.h:71
int reconnect_ok
Definition: zoom-p.h:74
char * tproxy
Definition: zoom-p.h:85
int preferred_message_size
Definition: zoom-p.h:104
char * charset
Definition: zoom-p.h:87
char * buf_out
Definition: zoom-p.h:82
char * sru_version
Definition: zoom-p.h:92
char * client_IP
Definition: zoom-p.h:91
ZOOM_Event m_queue_back
Definition: zoom-p.h:110
ZOOM_Event m_queue_front
Definition: zoom-p.h:109
char * password
Definition: zoom-p.h:96
char * group
Definition: zoom-p.h:95
ZOOM_resultset resultsets
Definition: zoom-p.h:108
char * cookie_out
Definition: zoom-p.h:89
char * cookie_in
Definition: zoom-p.h:90
ZOOM_options options
Definition: zoom-p.h:107
char * lang
Definition: zoom-p.h:88
char * proxy
Definition: zoom-p.h:84
enum oid_proto proto
Definition: zoom-p.h:66
zoom_sru_mode sru_mode
Definition: zoom-p.h:111
COMSTACK cs
Definition: zoom-p.h:67
ZOOM_task tasks
Definition: zoom-p.h:106
int support_named_resultsets
Definition: zoom-p.h:100
int maximum_record_size
Definition: zoom-p.h:103
char * user
Definition: zoom-p.h:94
char * host_port
Definition: zoom-p.h:68
WRBUF saveAPDU_wrbuf
Definition: zoom-p.h:118
char * addinfo
Definition: zoom-p.h:70
int url_authentication
Definition: zoom-p.h:97
yaz_cookies_t cookies
Definition: zoom-p.h:113
char * location
Definition: zoom-p.h:114
char * buf_in
Definition: zoom-p.h:80
ZOOM_options options
Definition: zoom-p.h:187
int refcount
Definition: zoom-p.h:185
char * buf_out
Definition: zoom-p.h:189
ZOOM_connection connection
Definition: zoom-p.h:188
int num_databaseNames
Definition: zoom-p.h:146
char ** facets_names
Definition: zoom-p.h:155
ZOOM_query query
Definition: zoom-p.h:135
ZOOM_options options
Definition: zoom-p.h:143
char * req_facets
Definition: zoom-p.h:152
int num_res_facets
Definition: zoom-p.h:154
ZOOM_resultset next
Definition: zoom-p.h:151
ZOOM_facet_field * res_facets
Definition: zoom-p.h:153
Odr_int size
Definition: zoom-p.h:137
char * setname
Definition: zoom-p.h:140
YAZ_MUTEX mutex
Definition: zoom-p.h:147
Z_SortKeySpecList * r_sort_spec
Definition: zoom-p.h:134
char ** databaseNames
Definition: zoom-p.h:145
ZOOM_record_cache record_hash[RECORD_HASH_SIZE]
Definition: zoom-p.h:142
WRBUF mc_key
Definition: zoom-p.h:156
ZOOM_connection connection
Definition: zoom-p.h:144
struct WRBUF_shptr * record_wrbuf
Definition: zoom-p.h:149
int num_databaseNames
Definition: zoom-p.h:181
ZOOM_query query
Definition: zoom-p.h:176
int refcount
Definition: zoom-p.h:172
Z_SRW_scanResponse * srw_scan_response
Definition: zoom-p.h:178
char ** databaseNames
Definition: zoom-p.h:180
ZOOM_connection connection
Definition: zoom-p.h:175
ZOOM_options options
Definition: zoom-p.h:174
Z_ScanResponse * scan_response
Definition: zoom-p.h:177
ZOOM_scanset scan
Definition: zoom-p.h:209
ZOOM_package package
Definition: zoom-p.h:212
int running
Definition: zoom-p.h:194
struct ZOOM_task_p::@133::@134 search
struct ZOOM_task_p::@133::@136 sort
union ZOOM_task_p::@133 u
ZOOM_task next
Definition: zoom-p.h:219
int which
Definition: zoom-p.h:195
Z_TermInfo * termInfo
Definition: z-core.h:984
union Z_Entry::@63 u
int which
Definition: z-core.h:982
Definition: zgdu.h:68
Z_HTTP_Request * HTTP_Request
Definition: zgdu.h:72
int which
Definition: zgdu.h:69
Z_APDU * z3950
Definition: zgdu.h:71
union Z_GDU::@132 u
Z_HTTP_Response * HTTP_Response
Definition: zgdu.h:73
Z_HTTP_Header * headers
Definition: zgdu.h:52
char * method
Definition: zgdu.h:49
int code
Definition: zgdu.h:58
Z_HTTP_Header * headers
Definition: zgdu.h:60
char * version
Definition: zgdu.h:59
Z_Entry ** entries
Definition: z-core.h:976
Z_SRW_scanTerm * terms
Definition: srw.h:146
char * displayTerm
Definition: srw.h:141
Odr_int * numberOfRecords
Definition: srw.h:140
char * value
Definition: srw.h:139
Z_ListEntries * entries
Definition: z-core.h:969
Odr_int * globalOccurrences
Definition: z-core.h:997
Z_Term * term
Definition: z-core.h:992
Z_InternationalString * displayTerm
Definition: z-core.h:993
Odr_oct * general
Definition: z-core.h:539
union Z_Term::@48 u
int which
Definition: z-core.h:537
unsigned io_pending
Definition: comstack.h:63
enum oid_proto protocol
Definition: comstack.h:70
int len
Definition: odr.h:102
char * buf
Definition: odr.h:101
Definition: odr.h:125
string buffer
Definition: wrbuf.h:43
int cs_get_peer_certificate_x509(COMSTACK cs, char **buf, int *len)
Definition: tcpip.c:1563
void wrbuf_destroy(WRBUF b)
destroy WRBUF and its buffer
Definition: wrbuf.c:38
void wrbuf_rewind(WRBUF b)
empty WRBUF content (length of buffer set to 0)
Definition: wrbuf.c:47
WRBUF wrbuf_alloc(void)
construct WRBUF
Definition: wrbuf.c:25
void wrbuf_printf(WRBUF b, const char *fmt,...)
writes printf result to WRBUF
Definition: wrbuf.c:178
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
Definition: wrbuf.c:281
void wrbuf_write(WRBUF b, const char *buf, size_t size)
append constant size buffer to WRBUF
Definition: wrbuf.c:68
#define wrbuf_len(b)
Definition: wrbuf.h:250
struct wrbuf * WRBUF
Header for memory handling functions.
#define xstrdup(s)
utility macro which calls xstrdup_f
Definition: xmalloc.h:55
#define xfree(x)
utility macro which calls xfree_f
Definition: xmalloc.h:53
#define xmalloc(x)
utility macro which calls malloc_f
Definition: xmalloc.h:49
Header for common YAZ utilities.
#define Z_Term_general
Definition: z-core.h:547
#define Z_Entry_termInfo
Definition: z-core.h:986
#define Z_GDU_Z3950
Definition: zgdu.h:65
#define Z_GDU_HTTP_Response
Definition: zgdu.h:67
int z_GDU(ODR o, Z_GDU **p, int opt, const char *name)
Definition: zgdu.c:17
ZOOM_resultset_sort1(ZOOM_resultset r, const char *sort_type, const char *sort_spec)
Definition: zoom-c.c:815
static void clear_error(ZOOM_connection c)
Definition: zoom-c.c:103
ZOOM_resultset_get_facet_field(ZOOM_resultset r, const char *name)
Definition: zoom-c.c:1000
ZOOM_package_option_getl(ZOOM_package p, const char *key, int *lenp)
Definition: zoom-c.c:1415
ZOOM_package_option_get(ZOOM_package p, const char *key)
Definition: zoom-c.c:1409
ZOOM_scanset_term(ZOOM_scanset scan, size_t pos, size_t *occ, size_t *len)
Definition: zoom-c.c:1333
ZOOM_connection_search_pqf(ZOOM_connection c, const char *q)
Definition: zoom-c.c:722
ZOOM_connection_destroy(ZOOM_connection c)
Definition: zoom-c.c:605
ZOOM_resultset_option_set(ZOOM_resultset r, const char *key, const char *val)
Definition: zoom-c.c:1838
static int g_resultsets
Definition: zoom-c.c:661
static void resultset_destroy(ZOOM_resultset r)
Definition: zoom-c.c:868
static zoom_ret send_HTTP_redirect(ZOOM_connection c, const char *uri)
Definition: zoom-c.c:1507
zoom_ret ZOOM_send_GDU(ZOOM_connection c, Z_GDU *gdu)
Definition: zoom-c.c:1526
static int do_read(ZOOM_connection c)
Definition: zoom-c.c:1644
ZOOM_connection_error_x(ZOOM_connection c, const char **cp, const char **addinfo, const char **diagset)
Definition: zoom-c.c:1926
ZOOM_API(int)
Definition: zoom-c.c:166
ZOOM_resultset_facets_size(ZOOM_resultset r)
Definition: zoom-c.c:994
ZOOM_task ZOOM_connection_insert_task(ZOOM_connection c, int which)
Definition: zoom-c.c:171
ZOOM_connection_last_event(ZOOM_connection cs)
Definition: zoom-c.c:2035
ZOOM_scanset_size(ZOOM_scanset scan)
Definition: zoom-c.c:1263
zoom_ret ZOOM_send_buf(ZOOM_connection c)
Definition: zoom-c.c:1763
static zoom_ret send_package(ZOOM_connection c)
Definition: zoom-c.c:1244
ZOOM_resultset_size(ZOOM_resultset r)
Definition: zoom-c.c:899
ZOOM_resultset_record(ZOOM_resultset r, size_t pos)
Definition: zoom-c.c:1156
static zoom_sru_mode get_sru_mode_from_string(const char *s)
Definition: zoom-c.c:345
ZOOM_resultset_facets_names(ZOOM_resultset r)
Definition: zoom-c.c:1028
static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres)
Definition: zoom-c.c:1553
ZOOM_connection_error(ZOOM_connection c, const char **cp, const char **addinfo)
Definition: zoom-c.c:1951
static void get_cert(ZOOM_connection c)
Definition: zoom-c.c:1053
ZOOM_connection_option_setl(ZOOM_connection c, const char *key, const char *val, int len)
Definition: zoom-c.c:1825
ZOOM_package_option_setl(ZOOM_package p, const char *key, const char *val, int len)
Definition: zoom-c.c:1428
static void ZOOM_connection_do_io(ZOOM_connection c, int mask)
Definition: zoom-c.c:1957
ZOOM_resultset_sort(ZOOM_resultset r, const char *sort_type, const char *sort_spec)
Definition: zoom-c.c:808
ZOOM_scanset_option_set(ZOOM_scanset scan, const char *key, const char *val)
Definition: zoom-c.c:1371
ZOOM_scanset_display_term(ZOOM_scanset scan, size_t pos, size_t *occ, size_t *len)
Definition: zoom-c.c:1349
int ZOOM_uri_to_code(const char *uri)
Definition: zoom-c.c:89
void ZOOM_connection_show_task(ZOOM_task task)
Definition: zoom-c.c:129
ZOOM_connection_option_get(ZOOM_connection c, const char *key)
Definition: zoom-c.c:1770
int ZOOM_test_reconnect(ZOOM_connection c)
Definition: zoom-c.c:904
ZOOM_resultset_records(ZOOM_resultset r, ZOOM_record *recs, size_t start, size_t count)
Definition: zoom-c.c:973
void ZOOM_set_error(ZOOM_connection c, int error, const char *addinfo)
Definition: zoom-c.c:98
ZOOM_connection_errmsg(ZOOM_connection c)
Definition: zoom-c.c:1852
ZOOM_connection_create(ZOOM_options options)
Definition: zoom-c.c:237
ZOOM_package_option_set(ZOOM_package p, const char *key, const char *val)
Definition: zoom-c.c:1421
void ZOOM_connection_show_tasks(ZOOM_connection c)
Definition: zoom-c.c:145
ZOOM_resultset_option_get(ZOOM_resultset r, const char *key)
Definition: zoom-c.c:1832
ZOOM_connection_process(ZOOM_connection c)
process one event for connection
Definition: zoom-c.c:2057
ZOOM_connection_connect(ZOOM_connection c, const char *host, int portnum)
Definition: zoom-c.c:361
static void odr_wrbuf_write(ODR o, void *handle, int type, const char *buf, int len)
Definition: zoom-c.c:229
ZOOM_resultset_facets(ZOOM_resultset r)
Definition: zoom-c.c:1022
ZOOM_resultset_destroy(ZOOM_resultset r)
Definition: zoom-c.c:863
static zoom_ret do_connect(ZOOM_connection c)
Definition: zoom-c.c:1069
void ZOOM_connection_remove_task(ZOOM_connection c)
Definition: zoom-c.c:183
ZOOM_resultset_record_immediate(ZOOM_resultset s, size_t pos)
Definition: zoom-c.c:1143
static void ZOOM_scanset_term_x(ZOOM_scanset scan, size_t pos, size_t *occ, const char **value_term, size_t *value_len, const char **disp_term, size_t *disp_len)
Definition: zoom-c.c:1275
ZOOM_event_nonblock(int no, ZOOM_connection *cs)
process one event for one of connections given
Definition: zoom-c.c:2080
ZOOM_connection_search(ZOOM_connection c, ZOOM_query q)
Definition: zoom-c.c:735
ZOOM_connection_option_getl(ZOOM_connection c, const char *key, int *lenp)
Definition: zoom-c.c:1781
ZOOM_connection_scan(ZOOM_connection c, const char *start)
Definition: zoom-c.c:1177
ZOOM_diag_str(int error)
Definition: zoom-c.c:1876
static void initlog(void)
Definition: zoom-c.c:40
static zoom_ret do_connect_host(ZOOM_connection c, const char *logical_url)
Definition: zoom-c.c:1074
ZOOM_connection_option_set(ZOOM_connection c, const char *key, const char *val)
Definition: zoom-c.c:1801
ZOOM_connection_addinfo(ZOOM_connection c)
Definition: zoom-c.c:1860
ZOOM_connection_scan1(ZOOM_connection c, ZOOM_query q)
Definition: zoom-c.c:1191
ZOOM_task ZOOM_connection_add_task(ZOOM_connection c, int which)
Definition: zoom-c.c:153
int resultsets_count(void)
Definition: zoom-c.c:678
ZOOM_scanset_option_get(ZOOM_scanset scan, const char *key)
Definition: zoom-c.c:1365
ZOOM_resultset_get_facet_field_by_index(ZOOM_resultset r, int idx)
Definition: zoom-c.c:1012
ZOOM_connection_diagset(ZOOM_connection c)
Definition: zoom-c.c:1868
static int resultset_use(int delta)
Definition: zoom-c.c:667
ZOOM_package_destroy(ZOOM_package p)
Definition: zoom-c.c:1393
ZOOM_connection_new(const char *host, int portnum)
Definition: zoom-c.c:337
ZOOM_connection_package(ZOOM_connection c, ZOOM_options options)
Definition: zoom-c.c:1379
ZOOM_resultset ZOOM_resultset_create(void)
Definition: zoom-c.c:682
ZOOM_connection_errcode(ZOOM_connection c)
Definition: zoom-c.c:1846
ZOOM_facet_field_get_term(ZOOM_facet_field field, size_t idx, int *freq)
Definition: zoom-c.c:1046
void ZOOM_set_HTTP_error(ZOOM_connection c, int error, const char *addinfo, const char *addinfo2)
Definition: zoom-c.c:1546
static int log_api0
Definition: zoom-c.c:34
ZOOM_facet_field_term_count(ZOOM_facet_field field)
Definition: zoom-c.c:1040
void ZOOM_resultset_addref(ZOOM_resultset r)
Definition: zoom-c.c:649
ZOOM_facet_field_name(ZOOM_facet_field field)
Definition: zoom-c.c:1034
static void ZOOM_resultset_retrieve(ZOOM_resultset r, int force_sync, int start, int count)
Definition: zoom-c.c:921
ZOOM_scanset_destroy(ZOOM_scanset scan)
Definition: zoom-c.c:1228
char ** ZOOM_connection_get_databases(ZOOM_connection con, ZOOM_options options, int *num, ODR odr)
Definition: zoom-c.c:322
void ZOOM_connection_remove_tasks(ZOOM_connection c)
Definition: zoom-c.c:223
static int log_details0
Definition: zoom-c.c:35
ZOOM_connection_exec_task(ZOOM_connection c)
executes non-blocking tasks for connection
Definition: zoom-c.c:1435
static zoom_ret do_write_ex(ZOOM_connection c, char *buf_out, int len_out)
Definition: zoom-c.c:1720
void ZOOM_set_dset_error(ZOOM_connection c, int error, const char *dset, const char *addinfo, const char *addinfo2)
Definition: zoom-c.c:54
static YAZ_MUTEX g_resultset_mutex
Definition: zoom-c.c:662
ZOOM_Event ZOOM_Event_create(int kind)
Definition: zoom-event.c:42
ZOOM_Event ZOOM_connection_get_event(ZOOM_connection c)
Definition: zoom-event.c:52
void ZOOM_connection_put_event(ZOOM_connection c, ZOOM_Event event)
Definition: zoom-event.c:73
void ZOOM_Event_destroy(ZOOM_Event event)
Definition: zoom-event.c:90
void ZOOM_connection_remove_events(ZOOM_connection c)
Definition: zoom-event.c:95
void ZOOM_memcached_destroy(ZOOM_connection c)
int ZOOM_memcached_configure(ZOOM_connection c)
void ZOOM_memcached_resultset(ZOOM_resultset r, ZOOM_query q)
void ZOOM_memcached_init(ZOOM_connection c)
Internal header for ZOOM implementation.
struct ZOOM_task_p * ZOOM_task
Definition: zoom-p.h:59
#define STATE_CONNECTING
Definition: zoom-p.h:62
int ZOOM_handle_sru(ZOOM_connection c, Z_HTTP_Response *hres, zoom_ret *cret, char **addinfo)
Definition: zoom-sru.c:417
zoom_sru_mode
Definition: zoom-p.h:50
@ zoom_sru_get
Definition: zoom-p.h:53
@ zoom_sru_soap
Definition: zoom-p.h:52
@ zoom_sru_error
Definition: zoom-p.h:51
@ zoom_sru_post
Definition: zoom-p.h:54
@ zoom_sru_solr
Definition: zoom-p.h:55
zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c)
Definition: zoom-sru.c:145
void ZOOM_handle_Z3950_apdu(ZOOM_connection c, Z_APDU *apdu)
Definition: zoom-z3950.c:1699
zoom_ret ZOOM_connection_Z3950_send_scan(ZOOM_connection c)
Definition: zoom-z3950.c:819
Z_SortKeySpecList * ZOOM_query_get_sortspec(ZOOM_query s)
Definition: zoom-query.c:134
#define ZOOM_TASK_SCAN
Definition: zoom-p.h:207
zoom_ret send_Z3950_sort(ZOOM_connection c, ZOOM_resultset resultset)
Definition: zoom-z3950.c:1517
#define ZOOM_TASK_PACKAGE
Definition: zoom-p.h:211
zoom_ret ZOOM_connection_Z3950_send_init(ZOOM_connection c)
Definition: zoom-z3950.c:570
#define ZOOM_TASK_CONNECT
Definition: zoom-p.h:206
#define STATE_IDLE
Definition: zoom-p.h:61
#define RECORD_HASH_SIZE
Definition: zoom-p.h:131
#define ZOOM_TASK_SORT
Definition: zoom-p.h:213
Z_Query * ZOOM_query_get_Z_Query(ZOOM_query s)
Definition: zoom-query.c:129
zoom_ret ZOOM_connection_srw_send_scan(ZOOM_connection c)
Definition: zoom-sru.c:92
zoom_ret
Definition: zoom-p.h:222
@ zoom_pending
Definition: zoom-p.h:223
@ zoom_complete
Definition: zoom-p.h:224
#define ZOOM_TASK_SEARCH
Definition: zoom-p.h:197
zoom_ret ZOOM_connection_Z3950_search(ZOOM_connection c)
Definition: zoom-z3950.c:1627
ZOOM_record ZOOM_record_cache_lookup_i(ZOOM_resultset r, int pos, const char *syntax, const char *elementSetName, const char *schema)
#define STATE_ESTABLISHED
Definition: zoom-p.h:63
ZOOM_query_destroy(ZOOM_query s)
Definition: zoom-query.c:230
#define ZOOM_ERROR_NONE
Definition: zoom.h:127
#define ZOOM_SELECT_READ
select/poll socket mask: read
Definition: zoom.h:415
#define ZOOM_ERROR_UNSUPPORTED_QUERY
Definition: zoom.h:137
ZOOM_event(int no, ZOOM_connection *cs)
wait for events on connection(s) (BLOCKING)
Definition: zoom-socket.c:99
#define ZOOM_ERROR_MEMORY
Definition: zoom.h:129
#define ZOOM_EVENT_END
Definition: zoom.h:161
ZOOM_connection_get_timeout(ZOOM_connection c)
get timeout in seconds for ZOOM connection
ZOOM_resultset_cache_reset(ZOOM_resultset r)
#define ZOOM_ERROR_CQL_PARSE
Definition: zoom.h:139
ZOOM_query_prefix(ZOOM_query s, const char *str)
Definition: zoom-query.c:255
#define ZOOM_EVENT_RECV_APDU
Definition: zoom.h:158
ZOOM_options_destroy(ZOOM_options opt)
Definition: zoom-opt.c:134
#define ZOOM_ERROR_ES_INVALID_SYNTAX
Definition: zoom.h:145
#define ZOOM_ERROR_CCL_CONFIG
Definition: zoom.h:141
#define ZOOM_ERROR_MEMCACHED
Definition: zoom.h:146
#define ZOOM_ERROR_CQL_TRANSFORM
Definition: zoom.h:140
struct ZOOM_scanset_p * ZOOM_scanset
Definition: zoom.h:56
#define ZOOM_SELECT_EXCEPT
select/poll socket mask: except
Definition: zoom.h:419
#define ZOOM_ERROR_ES_INVALID_ACTION
Definition: zoom.h:143
ZOOM_options_getl(ZOOM_options opt, const char *name, int *lenp)
Definition: zoom-opt.c:186
#define ZOOM_EVENT_RECV_DATA
Definition: zoom.h:154
ZOOM_options_create_with_parent(ZOOM_options parent)
Definition: zoom-opt.c:81
#define ZOOM_ERROR_CONNECT
Definition: zoom.h:128
struct ZOOM_package_p * ZOOM_package
Definition: zoom.h:57
typedefZOOM_BEGIN_CDECL struct ZOOM_options_p * ZOOM_options
Definition: zoom.h:50
ZOOM_connection_set_mask(ZOOM_connection c, int mask)
set socket mask for connection (DO NOT call outside zoom)
ZOOM_options_get_int(ZOOM_options opt, const char *name, int defa)
Definition: zoom-opt.c:235
ZOOM_options_create_with_parent2(ZOOM_options parent1, ZOOM_options parent2)
Definition: zoom-opt.c:94
ZOOM_options_set(ZOOM_options opt, const char *name, const char *v)
Definition: zoom-opt.c:180
ZOOM_query_create(void)
Definition: zoom-query.c:213
#define ZOOM_ERROR_CCL_PARSE
Definition: zoom.h:142
#define ZOOM_ERROR_INTERNAL
Definition: zoom.h:134
ZOOM_resultset_release(ZOOM_resultset r)
ZOOM_connection_get_mask(ZOOM_connection c)
get socket mask for connection
#define ZOOM_ERROR_ES_INVALID_VERSION
Definition: zoom.h:144
#define ZOOM_EVENT_SEND_DATA
Definition: zoom.h:153
#define ZOOM_ERROR_CONNECTION_LOST
Definition: zoom.h:132
ZOOM_options_setl(ZOOM_options opt, const char *name, const char *value, int len)
Definition: zoom-opt.c:160
#define ZOOM_EVENT_CONNECT
Definition: zoom.h:152
#define ZOOM_ERROR_DECODE
Definition: zoom.h:131
#define ZOOM_ERROR_INVALID_QUERY
Definition: zoom.h:138
#define ZOOM_ERROR_UNSUPPORTED_PROTOCOL
Definition: zoom.h:136
struct ZOOM_connection_p * ZOOM_connection
Definition: zoom.h:52
ZOOM_connection_close(ZOOM_connection c)
ZOOM_connection_is_idle(ZOOM_connection c)
determines if connection is idle (no active or pending work)
#define ZOOM_EVENT_SEND_APDU
Definition: zoom.h:157
ZOOM_options_get(ZOOM_options opt, const char *name)
Definition: zoom-opt.c:216
ZOOM_connection_get_socket(ZOOM_connection c)
get socket fd for ZOOM connection
ZOOM_connection_fire_event_socket(ZOOM_connection c, int mask)
fire socket event activity (read,write,except)
#define ZOOM_ERROR_TIMEOUT
Definition: zoom.h:135
#define ZOOM_EVENT_TIMEOUT
Definition: zoom.h:155
ZOOM_connection_fire_event_timeout(ZOOM_connection c)
fire socket event timeout
#define ZOOM_EVENT_NONE
Definition: zoom.h:151
ZOOM_query_addref(ZOOM_query s)
Definition: zoom-query.c:248
ZOOM_options_get_bool(ZOOM_options opt, const char *name, int defa)
Definition: zoom-opt.c:223
#define ZOOM_ERROR_INIT
Definition: zoom.h:133
ZOOM_query_sortby(ZOOM_query s, const char *criteria)
Definition: zoom-query.c:336
#define ZOOM_SELECT_WRITE
select/poll socket mask: write
Definition: zoom.h:417
#define ZOOM_ERROR_ENCODE
Definition: zoom.h:130
struct ZOOM_resultset_p * ZOOM_resultset
Definition: zoom.h:53