From 67940e6310f39f7e289d48a7d1fbb577eca56686 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Sun, 2 Jun 2002 21:27:17 +0000 Subject: [PATCH] First work on extended packages. Reconnect capability --- include/yaz/zoom.h | 45 +++++- zoom/Makefile.am | 4 +- zoom/zoom-c.c | 434 +++++++++++++++++++++++++++++++++++++++++++++------- zoom/zoom-opt.c | 53 +++++-- zoom/zoom-p.h | 18 ++- zoom/zoomsh.c | 77 +++++++++- 6 files changed, 551 insertions(+), 80 deletions(-) diff --git a/include/yaz/zoom.h b/include/yaz/zoom.h index 50b448b..5775453 100644 --- a/include/yaz/zoom.h +++ b/include/yaz/zoom.h @@ -1,6 +1,6 @@ /* * Public header for ZOOM C. - * $Id: zoom.h,v 1.12 2002-05-17 12:48:29 adam Exp $ + * $Id: zoom.h,v 1.13 2002-06-02 21:27:17 adam Exp $ */ #include @@ -26,6 +26,9 @@ typedef struct ZOOM_resultset_p *ZOOM_resultset; typedef struct ZOOM_task_p *ZOOM_task; typedef struct ZOOM_record_p *ZOOM_record; typedef struct ZOOM_scanset_p *ZOOM_scanset; +typedef struct ZOOM_package_p *ZOOM_package; + +typedef const char *(*ZOOM_options_callback)(void *handle, const char *name); /* ----------------------------------------------------------- */ /* connections */ @@ -179,25 +182,47 @@ ZOOM_API(void) ZOOM_scanset_destroy (ZOOM_scanset scan); ZOOM_API(const char *) -ZOOM_scanset_option_get (ZOOM_scanset scan, const char *key); + ZOOM_scanset_option_get (ZOOM_scanset scan, const char *key); + +ZOOM_API(void) + ZOOM_scanset_option_set (ZOOM_scanset scan, const char *key, + const char *val); +/* ----------------------------------------------------------- */ +/* Extended Services Packages */ + +ZOOM_API(ZOOM_package) + ZOOM_connection_package (ZOOM_connection c, ZOOM_options options); + +ZOOM_API(void) + ZOOM_package_destroy(ZOOM_package p); + +ZOOM_API(void) + ZOOM_package_send (ZOOM_package p, const char *type); + +ZOOM_API(const char *) + ZOOM_package_option_get (ZOOM_package p, const char *key); ZOOM_API(void) -ZOOM_scanset_option_set (ZOOM_scanset scan, const char *key, - const char *val); + ZOOM_package_option_set (ZOOM_package p, const char *key, + const char *val); + /* ----------------------------------------------------------- */ /* options */ -typedef const char *(*ZOOM_options_callback)(void *handle, const char *name); ZOOM_API(ZOOM_options_callback) -ZOOM_options_set_callback (ZOOM_options opt, - ZOOM_options_callback c, - void *handle); + ZOOM_options_set_callback (ZOOM_options opt, + ZOOM_options_callback c, + void *handle); ZOOM_API(ZOOM_options) ZOOM_options_create (void); ZOOM_API(ZOOM_options) ZOOM_options_create_with_parent (ZOOM_options parent); +ZOOM_API(ZOOM_options) + ZOOM_options_create_with_parent2 (ZOOM_options parent1, + ZOOM_options parent2); + ZOOM_API(const char *) ZOOM_options_get (ZOOM_options opt, const char *name); @@ -205,6 +230,10 @@ ZOOM_API(void) ZOOM_options_set (ZOOM_options opt, const char *name, const char *v); ZOOM_API(void) +ZOOM_options_setl (ZOOM_options opt, const char *name, const char *value, + int len); + +ZOOM_API(void) ZOOM_options_destroy (ZOOM_options opt); ZOOM_API(int) diff --git a/zoom/Makefile.am b/zoom/Makefile.am index de0babf..24e7f4c 100644 --- a/zoom/Makefile.am +++ b/zoom/Makefile.am @@ -1,11 +1,11 @@ -## $Id: Makefile.am,v 1.3 2002-04-15 09:44:44 adam Exp $ +## $Id: Makefile.am,v 1.4 2002-06-02 21:27:17 adam Exp $ ## Copyright (C) 2001, Index Data AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LTLIBRARIES = libzoom.la libzoom_la_SOURCES = zoom-opt.c zoom-c.c zoom-p.h -zoomlibs = libzoom.la ../comstack/libcomstack.la ../z39.50/libz39.50.la ../zutil/libzutil.la ../odr/libodr.la ../util/libutil.la $(READLINE_LIBS) +zoomlibs = libzoom.la ../comstack/libcomstack.la ../z39.50/libz39.50.la ../ill/libill.la ../zutil/libzutil.la ../odr/libodr.la ../util/libutil.la $(READLINE_LIBS) zoomsh_LDADD = $(zoomlibs) zoomtst1_LDADD = $(zoomlibs) diff --git a/zoom/zoom-c.c b/zoom/zoom-c.c index 27ae6f9..9bcbed4 100644 --- a/zoom/zoom-c.c +++ b/zoom/zoom-c.c @@ -1,5 +1,5 @@ /* - * $Id: zoom-c.c,v 1.32 2002-05-21 19:39:57 adam Exp $ + * $Id: zoom-c.c,v 1.33 2002-06-02 21:27:17 adam Exp $ * * ZOOM layer for C, connections, result sets, queries. */ @@ -10,6 +10,7 @@ #include #include #include +#include #include "zoom-p.h" @@ -18,6 +19,7 @@ #endif static int ZOOM_connection_send_init (ZOOM_connection c); +static int do_write_ex (ZOOM_connection c, char *buf_out, int len_out); static ZOOM_Event ZOOM_Event_create (int kind) { @@ -100,6 +102,19 @@ ZOOM_task ZOOM_connection_add_task (ZOOM_connection c, int which) return *taskp; } +ZOOM_task ZOOM_connection_insert_task (ZOOM_connection c, int which) +{ + ZOOM_task task = (ZOOM_task) xmalloc (sizeof(*task)); + + task->next = c->tasks; + c->tasks = task; + + task->running = 0; + task->which = which; + clear_error (c); + return task; +} + void ZOOM_connection_remove_task (ZOOM_connection c) { ZOOM_task task = c->tasks; @@ -120,6 +135,9 @@ void ZOOM_connection_remove_task (ZOOM_connection c) case ZOOM_TASK_SCAN: ZOOM_scanset_destroy (task->u.scan.scan); break; + case ZOOM_TASK_PACKAGE: + ZOOM_package_destroy (task->u.package); + break; default: assert (0); } @@ -144,6 +162,7 @@ ZOOM_connection_create (ZOOM_options options) c->cs = 0; c->mask = 0; + c->reconnect_ok = 0; c->state = STATE_IDLE; c->error = ZOOM_ERROR_NONE; c->addinfo = 0; @@ -162,6 +181,7 @@ ZOOM_connection_create (ZOOM_options options) c->cookie_out = 0; c->cookie_in = 0; + c->client_IP = 0; c->tasks = 0; c->odr_in = odr_createmem (ODR_DECODE); @@ -241,29 +261,38 @@ ZOOM_connection_new (const char *host, int portnum) ZOOM_API(void) ZOOM_connection_connect(ZOOM_connection c, - const char *host, int portnum) + const char *host, int portnum) { const char *val; ZOOM_task task; + if (c->cs) + { + c->reconnect_ok = 1; + return; + } + xfree (c->proxy); val = ZOOM_options_get (c->options, "proxy"); if (val && *val) c->proxy = xstrdup (val); else c->proxy = 0; + xfree (c->charset); val = ZOOM_options_get (c->options, "charset"); if (val && *val) c->charset = xstrdup (val); else c->charset = 0; + xfree (c->lang); val = ZOOM_options_get (c->options, "lang"); if (val && *val) c->lang = xstrdup (val); else c->lang = 0; + xfree (c->host_port); if (portnum) { char hostn[128]; @@ -275,6 +304,14 @@ ZOOM_connection_connect(ZOOM_connection c, ZOOM_options_set(c->options, "host", c->host_port); + val = ZOOM_options_get (c->options, "cookie"); + if (val && *val) + c->cookie_out = xstrdup (val); + + val = ZOOM_options_get (c->options, "clientIP"); + if (val && *val) + c->client_IP = xstrdup (val); + c->async = ZOOM_options_get_bool (c->options, "async", 0); c->error = ZOOM_ERROR_NONE; @@ -361,6 +398,7 @@ ZOOM_connection_destroy(ZOOM_connection c) xfree (c->lang); xfree (c->cookie_out); xfree (c->cookie_in); + xfree (c->client_IP); xfree (c); } @@ -494,7 +532,7 @@ static void do_close (ZOOM_connection c) } static void ZOOM_resultset_retrieve (ZOOM_resultset r, - int force_sync, int start, int count) + int force_sync, int start, int count) { ZOOM_task task; ZOOM_connection c; @@ -518,7 +556,7 @@ static void ZOOM_resultset_retrieve (ZOOM_resultset r, ZOOM_API(void) ZOOM_resultset_records (ZOOM_resultset r, ZOOM_record *recs, - size_t start, size_t count) + size_t start, size_t count) { int force_present = 0; @@ -553,7 +591,6 @@ static int do_connect (ZOOM_connection c) if (c->cs) { int ret = cs_connect (c->cs, add); - yaz_log (LOG_DEBUG, "cs_connect returned %d", ret); if (ret == 0) { ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_CONNECT); @@ -594,27 +631,29 @@ int z3950_connection_mask(ZOOM_connection c) static int encode_APDU(ZOOM_connection c, Z_APDU *a, ODR out) { - char str[120]; - assert (a); - sprintf (str, "send_APDU t=%p type=%d", c, a->which); if (c->cookie_out) { Z_OtherInformation **oi; yaz_oi_APDU(a, &oi); yaz_oi_set_string_oidval(oi, out, VAL_COOKIE, 1, c->cookie_out); } + if (c->client_IP) + { + Z_OtherInformation **oi; + yaz_oi_APDU(a, &oi); + yaz_oi_set_string_oidval(oi, out, VAL_CLIENT_IP, 1, c->client_IP); + } if (!z_APDU(out, &a, 0, 0)) { - FILE *outf = fopen("/tmp/apdu.txt", "w"); - if (outf) + FILE *outf = fopen("/tmp/apdu.txt", "a"); + if (a && outf) { ODR odr_pr = odr_createmem(ODR_PRINT); fprintf (outf, "a=%p\n", a); odr_setprint(odr_pr, outf); z_APDU(odr_pr, &a, 0, 0); odr_destroy(odr_pr); - fclose (outf); } c->error = ZOOM_ERROR_ENCODE; do_close (c); @@ -635,7 +674,7 @@ static int send_APDU (ZOOM_connection c, Z_APDU *a) ZOOM_connection_put_event (c, event); odr_reset(c->odr_out); do_write (c); - return 0; + return 0; } static int ZOOM_connection_send_init (ZOOM_connection c) @@ -866,7 +905,6 @@ static int ZOOM_connection_send_search (ZOOM_connection c) search_req->resultSetName = odr_strdup(c->odr_out, r->setname); /* send search request */ send_APDU (c, apdu); - r->r_query = 0; return 1; } @@ -959,7 +997,8 @@ ZOOM_record_get (ZOOM_record rec, const char *type, int *len) return 0; if (!strcmp (type, "database")) { - if (len) *len = strlen(npr->databaseName)+1; + if (len) + *len = strlen(npr->databaseName); return npr->databaseName; } else if (!strcmp (type, "syntax")) @@ -970,7 +1009,8 @@ ZOOM_record_get (ZOOM_record rec, const char *type, int *len) oident *ent = oid_getentbyoid(r->direct_reference); if (ent) { - if (len) *len = strlen(ent->desc)+1; + if (len) + *len = strlen(ent->desc); return ent->desc; } } @@ -1071,25 +1111,7 @@ ZOOM_record_get (ZOOM_record rec, const char *type, int *len) else if (!strcmp (type, "raw")) { if (npr->which == Z_NamePlusRecord_databaseRecord) - { - Z_External *r = (Z_External *) npr->u.databaseRecord; - - if (r->which == Z_External_sutrs) - { - if (len) *len = r->u.sutrs->len; - return (const char *) r->u.sutrs->buf; - } - else if (r->which == Z_External_octet) - { - if (len) *len = r->u.octet_aligned->len; - return (const char *) r->u.octet_aligned->buf; - } - else /* grs-1, explain, ... */ - { - if (len) *len = -1; - return (const char *) npr->u.databaseRecord; - } - } + return (const char *) npr->u.databaseRecord; return 0; } return 0; @@ -1463,6 +1485,21 @@ ZOOM_scanset_destroy (ZOOM_scanset scan) } } +static int send_package (ZOOM_connection c) +{ + ZOOM_Event event; + if (!c->tasks) + return 0; + assert (c->tasks->which == ZOOM_TASK_PACKAGE); + + event = ZOOM_Event_create (ZOOM_EVENT_SEND_APDU); + ZOOM_connection_put_event (c, event); + + do_write_ex (c, c->tasks->u.package->buf_out, + c->tasks->u.package->len_out); + return 1; +} + static int send_scan (ZOOM_connection c) { ZOOM_scanset scan; @@ -1542,6 +1579,242 @@ ZOOM_scanset_option_set (ZOOM_scanset scan, const char *key, ZOOM_options_set (scan->options, key, val); } + + +static Z_APDU *create_es_package (ZOOM_package p, int type) +{ + const char *str; + Z_APDU *apdu = zget_APDU(p->odr_out, Z_APDU_extendedServicesRequest); + Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest; + + *req->function = Z_ExtendedServicesRequest_create; + + str = ZOOM_options_get(p->options, "package-name"); + if (str && *str) + req->packageName = nmem_strdup (p->odr_out->mem, str); + + str = ZOOM_options_get(p->options, "user-id"); + if (str) + req->userId = nmem_strdup (p->odr_out->mem, str); + + req->packageType = yaz_oidval_to_z3950oid(p->odr_out, CLASS_EXTSERV, + type); + + str = ZOOM_options_get(p->options, "function"); + if (str) + { + if (!strcmp (str, "create")) + *req->function = 1; + if (!strcmp (str, "delete")) + *req->function = 2; + if (!strcmp (str, "modify")) + *req->function = 3; + } + return apdu; +} + +static const char *ill_array_lookup (void *clientData, const char *idx) +{ + ZOOM_package p = (ZOOM_package) clientData; + return ZOOM_options_get (p->options, idx+4); +} + +static Z_External *encode_ill_request (ZOOM_package p) +{ + ODR out = p->odr_out; + ILL_Request *req; + Z_External *r = 0; + struct ill_get_ctl ctl; + + ctl.odr = p->odr_out; + ctl.clientData = p; + ctl.f = ill_array_lookup; + + req = ill_get_ILLRequest(&ctl, "ill", 0); + + if (!ill_Request (out, &req, 0, 0)) + { + int ill_request_size; + char *ill_request_buf = odr_getbuf (out, &ill_request_size, 0); + if (ill_request_buf) + odr_setbuf (out, ill_request_buf, ill_request_size, 1); + return 0; + } + else + { + oident oid; + int illRequest_size = 0; + char *illRequest_buf = odr_getbuf (out, &illRequest_size, 0); + + oid.proto = PROTO_GENERAL; + oid.oclass = CLASS_GENERAL; + oid.value = VAL_ISO_ILL_1; + + r = (Z_External *) odr_malloc (out, sizeof(*r)); + r->direct_reference = odr_oiddup(out,oid_getoidbyent(&oid)); + r->indirect_reference = 0; + r->descriptor = 0; + r->which = Z_External_single; + + r->u.single_ASN1_type = (Odr_oct *) + odr_malloc (out, sizeof(*r->u.single_ASN1_type)); + r->u.single_ASN1_type->buf = odr_malloc (out, illRequest_size); + r->u.single_ASN1_type->len = illRequest_size; + r->u.single_ASN1_type->size = illRequest_size; + memcpy (r->u.single_ASN1_type->buf, illRequest_buf, illRequest_size); + } + return r; +} + +static Z_ItemOrder *encode_item_order(ZOOM_package p) +{ + Z_ItemOrder *req = odr_malloc (p->odr_out, sizeof(*req)); + const char *str; + + req->which=Z_IOItemOrder_esRequest; + req->u.esRequest = (Z_IORequest *) + odr_malloc(p->odr_out,sizeof(Z_IORequest)); + + /* to keep part ... */ + req->u.esRequest->toKeep = (Z_IOOriginPartToKeep *) + odr_malloc(p->odr_out,sizeof(Z_IOOriginPartToKeep)); + req->u.esRequest->toKeep->supplDescription = 0; + req->u.esRequest->toKeep->contact = + odr_malloc (p->odr_out, sizeof(*req->u.esRequest->toKeep->contact)); + + str = ZOOM_options_get(p->options, "contact-name"); + req->u.esRequest->toKeep->contact->name = str ? + nmem_strdup (p->odr_out->mem, str) : 0; + + str = ZOOM_options_get(p->options, "contact-phone"); + req->u.esRequest->toKeep->contact->phone = str ? + nmem_strdup (p->odr_out->mem, str) : 0; + + str = ZOOM_options_get(p->options, "contact-email"); + req->u.esRequest->toKeep->contact->email = str ? + nmem_strdup (p->odr_out->mem, str) : 0; + + req->u.esRequest->toKeep->addlBilling = 0; + + /* not to keep part ... */ + req->u.esRequest->notToKeep = (Z_IOOriginPartNotToKeep *) + odr_malloc(p->odr_out,sizeof(Z_IOOriginPartNotToKeep)); + + req->u.esRequest->notToKeep->resultSetItem = (Z_IOResultSetItem *) + odr_malloc(p->odr_out, sizeof(Z_IOResultSetItem)); + + str = ZOOM_options_get(p->options, "itemorder-setname"); + if (!str) + str = "default"; + req->u.esRequest->notToKeep->resultSetItem->resultSetId = + nmem_strdup (p->odr_out->mem, str); + req->u.esRequest->notToKeep->resultSetItem->item = + (int *) odr_malloc(p->odr_out, sizeof(int)); + + str = ZOOM_options_get(p->options, "itemorder-item"); + *req->u.esRequest->notToKeep->resultSetItem->item = + (str ? atoi(str) : 1); + + req->u.esRequest->notToKeep->itemRequest = encode_ill_request(p); + + return req; +} + +ZOOM_API(void) + ZOOM_package_send (ZOOM_package p, const char *type) +{ + Z_APDU *apdu = 0; + ZOOM_connection c; + if (!p) + return; + c = p->connection; + odr_reset (p->odr_out); + xfree (p->buf_out); + p->buf_out = 0; + if (!strcmp(type, "itemorder")) + { + Z_External *r; + apdu = create_es_package (p, VAL_ITEMORDER); + if (apdu) + { + r = odr_malloc (p->odr_out, sizeof(*r)); + + r->direct_reference = + yaz_oidval_to_z3950oid(p->odr_out, CLASS_EXTSERV, + VAL_ITEMORDER); + r->descriptor = 0; + r->which = Z_External_itemOrder; + r->indirect_reference = 0; + r->u.itemOrder = encode_item_order (p); + + apdu->u.extendedServicesRequest->taskSpecificParameters = r; + } + } + if (apdu) + { + if (encode_APDU(p->connection, apdu, p->odr_out) == 0) + { + char *buf; + + ZOOM_task task = ZOOM_connection_add_task (c, ZOOM_TASK_PACKAGE); + task->u.package = p; + buf = odr_getbuf(p->odr_out, &p->len_out, 0); + p->buf_out = xmalloc (p->len_out); + memcpy (p->buf_out, buf, p->len_out); + + (p->refcount)++; + if (!c->async) + { + while (ZOOM_event (1, &c)) + ; + } + } + } +} + +ZOOM_API(ZOOM_package) + ZOOM_connection_package (ZOOM_connection c, ZOOM_options options) +{ + ZOOM_package p = (ZOOM_package) xmalloc (sizeof(*p)); + + p->connection = c; + p->odr_out = odr_createmem (ODR_ENCODE); + p->options = ZOOM_options_create_with_parent2 (options, c->options); + p->refcount = 1; + p->buf_out = 0; + p->len_out = 0; + return p; +} + +ZOOM_API(void) + ZOOM_package_destroy(ZOOM_package p) +{ + if (!p) + return; + (p->refcount)--; + if (p->refcount == 0) + { + odr_destroy (p->odr_out); + xfree (p->buf_out); + + ZOOM_options_destroy (p->options); + xfree (p); + } +} + +ZOOM_API(const char *) +ZOOM_package_option_get (ZOOM_package p, const char *key) +{ + return ZOOM_options_get (p->options, key); +} + +ZOOM_API(void) +ZOOM_package_option_set (ZOOM_package p, const char *key, + const char *val) +{ + ZOOM_options_set (p->options, key, val); +} + static int ZOOM_connection_exec_task (ZOOM_connection c) { ZOOM_task task = c->tasks; @@ -1555,7 +1828,8 @@ static int ZOOM_connection_exec_task (ZOOM_connection c) ZOOM_connection_remove_tasks (c); return 0; } - yaz_log (LOG_DEBUG, "ZOOM_connection_exec_task type=%d", task->which); + yaz_log (LOG_DEBUG, "ZOOM_connection_exec_task type=%d run=%d", + task->which, task->running); if (task->running) return 0; task->running = 1; @@ -1577,6 +1851,10 @@ static int ZOOM_connection_exec_task (ZOOM_connection c) case ZOOM_TASK_SCAN: if (send_scan(c)) return 1; + break; + case ZOOM_TASK_PACKAGE: + if (send_package(c)) + return 1; } ZOOM_connection_remove_task (c); return 0; @@ -1590,6 +1868,27 @@ static int send_sort_present (ZOOM_connection c) return r; } +static int es_response (ZOOM_connection c, + Z_ExtendedServicesResponse *res) +{ + if (!c->tasks || c->tasks->which != ZOOM_TASK_PACKAGE) + return 0; + if (res->diagnostics && res->num_diagnostics > 0) + response_diag(c, res->diagnostics[0]); + if (res->taskPackage && + res->taskPackage->which == Z_External_extendedService) + { + Z_TaskPackage *taskPackage = res->taskPackage->u.extendedService; + Odr_oct *id = taskPackage->targetReference; + + if (id) + ZOOM_options_setl (c->tasks->u.package->options, + "targetReference", id->buf, id->len); + } + return 1; +} + + static void handle_apdu (ZOOM_connection c, Z_APDU *apdu) { Z_InitResponse *initrs; @@ -1625,21 +1924,22 @@ static void handle_apdu (ZOOM_connection c, Z_APDU *apdu) } if (ODR_MASK_GET(initrs->options, Z_Options_negotiationModel)) { - NMEM tmpmem = nmem_create(); - Z_CharSetandLanguageNegotiation *p = - yaz_get_charneg_record(initrs->otherInfo); - - if (p) - { - char *charset=NULL, *lang=NULL; - int selected; - - yaz_get_response_charneg(tmpmem, p, &charset, &lang, &selected); - yaz_log(LOG_DEBUG, "Target accepted: charset - %s, language - %s, select - %d", - charset, lang, selected); - - nmem_destroy(tmpmem); - } + NMEM tmpmem = nmem_create(); + Z_CharSetandLanguageNegotiation *p = + yaz_get_charneg_record(initrs->otherInfo); + + if (p) + { + char *charset=NULL, *lang=NULL; + int selected; + + yaz_get_response_charneg(tmpmem, p, &charset, &lang, &selected); + yaz_log(LOG_DEBUG, "Target accepted: charset - %s," + "language - %s, select - %d", + charset, lang, selected); + + nmem_destroy(tmpmem); + } } break; case Z_APDU_searchResponse: @@ -1660,6 +1960,11 @@ static void handle_apdu (ZOOM_connection c, Z_APDU *apdu) case Z_APDU_scanResponse: scan_response (c, apdu->u.scanResponse); ZOOM_connection_remove_task (c); + break; + case Z_APDU_extendedServicesResponse: + es_response (c, apdu->u.extendedServicesResponse); + ZOOM_connection_remove_task (c); + break; } } @@ -1672,17 +1977,31 @@ static int do_read (ZOOM_connection c) event = ZOOM_Event_create (ZOOM_EVENT_RECV_DATA); ZOOM_connection_put_event (c, event); + yaz_log (LOG_DEBUG, "do_read len=%d", c->len_in); + r = cs_get (c->cs, &c->buf_in, &c->len_in); if (r == 1) return 0; if (r <= 0) { - c->error= ZOOM_ERROR_CONNECTION_LOST; - do_close (c); + if (c->reconnect_ok) + { + do_close (c); + c->reconnect_ok = 0; + yaz_log (LOG_DEBUG, "reconnect read"); + c->tasks->running = 0; + ZOOM_connection_insert_task (c, ZOOM_TASK_CONNECT); + } + else + { + c->error= ZOOM_ERROR_CONNECTION_LOST; + do_close (c); + } } else { ZOOM_Event event; + c->reconnect_ok = 0; odr_reset (c->odr_in); odr_setbuf (c->odr_in, c->buf_in, r, 0); event = ZOOM_Event_create (ZOOM_EVENT_RECV_APDU); @@ -1708,8 +2027,18 @@ static int do_write_ex (ZOOM_connection c, char *buf_out, int len_out) event = ZOOM_Event_create(ZOOM_EVENT_SEND_DATA); ZOOM_connection_put_event (c, event); + yaz_log (LOG_DEBUG, "do_write_ex len=%d", len_out); if ((r=cs_put (c->cs, buf_out, len_out)) < 0) { + if (c->reconnect_ok) + { + do_close (c); + c->reconnect_ok = 0; + yaz_log (LOG_DEBUG, "reconnect write"); + c->tasks->running = 0; + ZOOM_connection_insert_task (c, ZOOM_TASK_CONNECT); + return 0; + } if (c->state == STATE_CONNECTING) c->error = ZOOM_ERROR_CONNECT; else @@ -1728,6 +2057,7 @@ static int do_write_ex (ZOOM_connection c, char *buf_out, int len_out) } else { + // c->reconnect_ok = 0; c->mask = ZOOM_SELECT_READ|ZOOM_SELECT_EXCEPT; yaz_log (LOG_DEBUG, "do_write_ex 2 mask=%d", c->mask); } diff --git a/zoom/zoom-opt.c b/zoom/zoom-opt.c index 883a5a3..309e8cf 100644 --- a/zoom/zoom-opt.c +++ b/zoom/zoom-opt.c @@ -1,5 +1,5 @@ /* - * $Id: zoom-opt.c,v 1.5 2002-05-17 12:48:30 adam Exp $ + * $Id: zoom-opt.c,v 1.6 2002-06-02 21:27:17 adam Exp $ * * ZOOM layer for C, options handling */ @@ -10,13 +10,20 @@ #include "zoom-p.h" ZOOM_API(ZOOM_options) +ZOOM_options_create_with_parent (ZOOM_options parent) +{ + return ZOOM_options_create_with_parent2(parent, 0); +} + +ZOOM_API(ZOOM_options) ZOOM_options_create (void) { return ZOOM_options_create_with_parent (0); } + ZOOM_API(ZOOM_options) -ZOOM_options_create_with_parent (ZOOM_options parent) +ZOOM_options_create_with_parent2 (ZOOM_options parent1, ZOOM_options parent2) { ZOOM_options opt = (ZOOM_options) xmalloc (sizeof(*opt)); @@ -24,12 +31,16 @@ ZOOM_options_create_with_parent (ZOOM_options parent) opt->callback_func = 0; opt->callback_handle = 0; opt->entries = 0; - opt->parent= parent; - if (parent) - (parent->refcount)++; + opt->parent1= parent1; + if (parent1) + (parent1->refcount)++; + opt->parent2= parent2; + if (parent2) + (parent2->refcount)++; return opt; } + void ZOOM_options_addref (ZOOM_options opt) { (opt->refcount)++; @@ -60,7 +71,8 @@ ZOOM_options_destroy (ZOOM_options opt) { struct ZOOM_options_entry *e; - ZOOM_options_destroy (opt->parent); + ZOOM_options_destroy (opt->parent1); + ZOOM_options_destroy (opt->parent2); e = opt->entries; while (e) { @@ -75,7 +87,8 @@ ZOOM_options_destroy (ZOOM_options opt) } ZOOM_API(void) -ZOOM_options_set (ZOOM_options opt, const char *name, const char *value) +ZOOM_options_setl (ZOOM_options opt, const char *name, const char *value, + int len) { struct ZOOM_options_entry **e; @@ -85,17 +98,35 @@ ZOOM_options_set (ZOOM_options opt, const char *name, const char *value) if (!strcmp((*e)->name, name)) { xfree ((*e)->value); - (*e)->value = xstrdup(value); + (*e)->value = 0; + if (value) + { + (*e)->value = xmalloc (len+1); + memcpy ((*e)->value, value, len); + (*e)->value[len] = '\0'; + } return; } e = &(*e)->next; } *e = (struct ZOOM_options_entry *) xmalloc (sizeof(**e)); (*e)->name = xstrdup (name); - (*e)->value = xstrdup (value); + (*e)->value = 0; + if (value) + { + (*e)->value = xmalloc (len+1); + memcpy ((*e)->value, value, len); + (*e)->value[len] = '\0'; + } (*e)->next = 0; } +ZOOM_API(void) +ZOOM_options_set (ZOOM_options opt, const char *name, const char *value) +{ + return ZOOM_options_setl (opt, name, value, value ? strlen(value): 0); +} + ZOOM_API(const char *) ZOOM_options_get (ZOOM_options opt, const char *name) { @@ -115,7 +146,9 @@ ZOOM_options_get (ZOOM_options opt, const char *name) } } if (!v) - return ZOOM_options_get(opt->parent, name); + v = ZOOM_options_get(opt->parent1, name); + if (!v) + v = ZOOM_options_get(opt->parent2, name); return v; } diff --git a/zoom/zoom-p.h b/zoom/zoom-p.h index 65621a8..be5f4ef 100644 --- a/zoom/zoom-p.h +++ b/zoom/zoom-p.h @@ -1,6 +1,6 @@ /* * Private C header for ZOOM C. - * $Id: zoom-p.h,v 1.10 2002-05-18 09:52:37 oleg Exp $ + * $Id: zoom-p.h,v 1.11 2002-06-02 21:27:17 adam Exp $ */ #include #include @@ -32,6 +32,7 @@ struct ZOOM_connection_p { char *addinfo; int state; int mask; + int reconnect_ok; ODR odr_in; ODR odr_out; char *buf_in; @@ -43,6 +44,7 @@ struct ZOOM_connection_p { char *lang; char *cookie_out; char *cookie_in; + char *client_IP; int async; int support_named_resultsets; int last_event; @@ -65,7 +67,8 @@ struct ZOOM_options_p { void *callback_handle; ZOOM_options_callback callback_func; struct ZOOM_options_entry *entries; - ZOOM_options parent; + ZOOM_options parent1; + ZOOM_options parent2; }; typedef struct ZOOM_record_cache_p *ZOOM_record_cache; @@ -110,6 +113,15 @@ struct ZOOM_scanset_p { Z_ScanResponse *scan_response; }; +struct ZOOM_package_p { + int refcount; + ODR odr_out; + ZOOM_options options; + ZOOM_connection connection; + char *buf_out; + int len_out; +}; + struct ZOOM_task_p { int running; int which; @@ -129,6 +141,8 @@ struct ZOOM_task_p { struct { ZOOM_scanset scan; } scan; +#define ZOOM_TASK_PACKAGE 5 + ZOOM_package package; } u; ZOOM_task next; }; diff --git a/zoom/zoomsh.c b/zoom/zoomsh.c index f263768..3890467 100644 --- a/zoom/zoomsh.c +++ b/zoom/zoomsh.c @@ -1,5 +1,5 @@ /* - * $Id: zoomsh.c,v 1.9 2002-05-18 09:52:37 oleg Exp $ + * $Id: zoomsh.c,v 1.10 2002-06-02 21:27:17 adam Exp $ * * ZOOM-C Shell */ @@ -76,12 +76,25 @@ static void cmd_set (ZOOM_connection *c, ZOOM_resultset *r, return ; } if (!next_token_copy (args, val, sizeof(val))) + ZOOM_options_set(options, key, 0); + else + ZOOM_options_set(options, key, val); +} + +static void cmd_get (ZOOM_connection *c, ZOOM_resultset *r, + ZOOM_options options, + const char **args) +{ + char key[40], val[80]; + if (!next_token_copy (args, key, sizeof(key))) { - const char *val = ZOOM_options_get(options, key); - printf ("%s = %s\n", key, val ? val : ""); + printf ("missing argument for get\n"); } else - ZOOM_options_set(options, key, val); + { + const char *val = ZOOM_options_get(options, key); + printf ("%s = %s\n", key, val ? val : ""); + } } static void cmd_close (ZOOM_connection *c, ZOOM_resultset *r, @@ -173,6 +186,48 @@ static void cmd_show (ZOOM_connection *c, ZOOM_resultset *r, } } +static void cmd_ext (ZOOM_connection *c, ZOOM_resultset *r, + ZOOM_options options, + const char **args) +{ + ZOOM_query s; + ZOOM_package p[MAX_CON]; + + int i; + + for (i = 0; i []\n"); printf ("quit\n"); printf ("close \n"); - printf ("set