X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=zoom%2Fzoom-c.c;h=522660a41031c729106568ca7010bcea624be7aa;hb=5ea4e843c189848da0b41935e7f2db8e41b7c8e7;hp=9bcbed4878998cb2ad7a7196c6f2e4fdc1bdf5b6;hpb=67940e6310f39f7e289d48a7d1fbb577eca56686;p=yaz-moved-to-github.git diff --git a/zoom/zoom-c.c b/zoom/zoom-c.c index 9bcbed4..522660a 100644 --- a/zoom/zoom-c.c +++ b/zoom/zoom-c.c @@ -1,5 +1,5 @@ /* - * $Id: zoom-c.c,v 1.33 2002-06-02 21:27:17 adam Exp $ + * $Id: zoom-c.c,v 1.42 2002-08-25 06:48:18 adam Exp $ * * ZOOM layer for C, connections, result sets, queries. */ @@ -151,9 +151,7 @@ void ZOOM_connection_remove_tasks (ZOOM_connection c) ZOOM_connection_remove_task(c); } -static ZOOM_record record_cache_lookup (ZOOM_resultset r, - int pos, - const char *elementSetName); +static ZOOM_record record_cache_lookup (ZOOM_resultset r, int pos); ZOOM_API(ZOOM_connection) ZOOM_connection_create (ZOOM_options options) @@ -208,10 +206,13 @@ static char **set_DatabaseNames (ZOOM_connection con, ZOOM_options options, if (!cp || !*cp) { - cp = strchr (con->host_port, '/'); + if (strncmp (con->host_port, "unix:", 5) == 0) + cp = strchr (con->host_port+5, ':'); + else + cp = strchr (con->host_port, '/'); if (cp) cp++; - } + } if (cp) { c = cp; @@ -268,9 +269,11 @@ ZOOM_connection_connect(ZOOM_connection c, if (c->cs) { + yaz_log (LOG_DEBUG, "reconnect"); c->reconnect_ok = 1; return; } + yaz_log(LOG_DEBUG, "connect"); xfree (c->proxy); val = ZOOM_options_get (c->options, "proxy"); if (val && *val) @@ -629,6 +632,39 @@ int z3950_connection_mask(ZOOM_connection c) return 0; } +static void otherInfo_attach (ZOOM_connection c, Z_APDU *a, ODR out) +{ + int i; + for (i = 0; i<200; i++) + { + size_t len; + Z_OtherInformation **oi; + char buf[20]; + const char *val; + const char *cp; + int oidval; + + sprintf (buf, "otherInfo%d", i); + val = ZOOM_options_get (c->options, buf); + if (!val) + break; + cp = strchr (val, ':'); + if (!cp) + continue; + len = cp - val; + if (len >= sizeof(buf)) + len = sizeof(buf)-1; + memcpy (buf, val, len); + buf[len] = '\0'; + oidval = oid_getvalbyname (buf); + if (oidval == VAL_NONE) + continue; + + yaz_oi_APDU(a, &oi); + yaz_oi_set_string_oidval(oi, out, oidval, 1, cp+1); + } +} + static int encode_APDU(ZOOM_connection c, Z_APDU *a, ODR out) { assert (a); @@ -644,6 +680,7 @@ static int encode_APDU(ZOOM_connection c, Z_APDU *a, ODR out) yaz_oi_APDU(a, &oi); yaz_oi_set_string_oidval(oi, out, VAL_CLIENT_IP, 1, c->client_IP); } + otherInfo_attach (c, a, out); if (!z_APDU(out, &a, 0, 0)) { FILE *outf = fopen("/tmp/apdu.txt", "a"); @@ -770,13 +807,14 @@ static int ZOOM_connection_send_init (ZOOM_connection c) if ((oi_unit = yaz_oi_update(oi, c->odr_out, NULL, 0, 0))) { - ODR_MASK_SET(ireq->options, Z_Options_negotiationModel); - - oi_unit->which = Z_OtherInfo_externallyDefinedInfo; - oi_unit->information.externallyDefinedInfo = - yaz_set_proposal_charneg(c->odr_out, - (const char **)&c->charset, (c->charset) ? 1:0, - (const char **)&c->lang, (c->lang) ? 1:0, 1); + ODR_MASK_SET(ireq->options, Z_Options_negotiationModel); + + oi_unit->which = Z_OtherInfo_externallyDefinedInfo; + oi_unit->information.externallyDefinedInfo = + yaz_set_proposal_charneg + (c->odr_out, + (const char **)&c->charset, (c->charset) ? 1:0, + (const char **)&c->lang, (c->lang) ? 1:0, 1); } } assert (apdu); @@ -961,7 +999,7 @@ ZOOM_record_clone (ZOOM_record srec) ZOOM_API(ZOOM_record) ZOOM_resultset_record_immediate (ZOOM_resultset s,size_t pos) { - return record_cache_lookup (s, pos, 0); + return record_cache_lookup (s, pos); } ZOOM_API(ZOOM_record) @@ -1111,18 +1149,44 @@ 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 0; + } + else if (!strcmp (type, "ext")) + { + if (npr->which == Z_NamePlusRecord_databaseRecord) return (const char *) npr->u.databaseRecord; return 0; } return 0; } -static void record_cache_add (ZOOM_resultset r, - Z_NamePlusRecord *npr, - int pos, - const char *elementSetName) +static void record_cache_add (ZOOM_resultset r, Z_NamePlusRecord *npr, int pos) { ZOOM_record_cache rc; + const char *elementSetName = + ZOOM_resultset_option_get (r, "elementSetName"); + const char *syntax = + ZOOM_resultset_option_get (r, "preferredRecordSyntax"); + for (rc = r->record_cache; rc; rc = rc->next) { @@ -1132,10 +1196,15 @@ static void record_cache_add (ZOOM_resultset r, || (elementSetName && rc->elementSetName && !strcmp (elementSetName, rc->elementSetName))) { - /* not destroying rc->npr (it's handled by nmem )*/ - rc->rec.npr = npr; - /* keeping wrbuf_marc too */ - return; + if ((!syntax && !rc->syntax) + || (syntax && rc->syntax && + !strcmp (syntax, rc->syntax))) + { + /* not destroying rc->npr (it's handled by nmem )*/ + rc->rec.npr = npr; + /* keeping wrbuf_marc too */ + return; + } } } } @@ -1147,17 +1216,25 @@ static void record_cache_add (ZOOM_resultset r, rc->elementSetName = odr_strdup (r->odr, elementSetName); else rc->elementSetName = 0; + + if (syntax) + rc->syntax = odr_strdup (r->odr, syntax); + else + rc->syntax = 0; + rc->pos = pos; rc->next = r->record_cache; r->record_cache = rc; } -static ZOOM_record record_cache_lookup (ZOOM_resultset r, - int pos, - const char *elementSetName) +static ZOOM_record record_cache_lookup (ZOOM_resultset r, int pos) { ZOOM_record_cache rc; - + const char *elementSetName = + ZOOM_resultset_option_get (r, "elementSetName"); + const char *syntax = + ZOOM_resultset_option_get (r, "preferredRecordSyntax"); + for (rc = r->record_cache; rc; rc = rc->next) { if (pos == rc->pos) @@ -1165,7 +1242,12 @@ static ZOOM_record record_cache_lookup (ZOOM_resultset r, if ((!elementSetName && !rc->elementSetName) || (elementSetName && rc->elementSetName && !strcmp (elementSetName, rc->elementSetName))) - return &rc->rec; + { + if ((!syntax && !rc->syntax) + || (syntax && rc->syntax && + !strcmp (syntax, rc->syntax))) + return &rc->rec; + } } } return 0; @@ -1219,7 +1301,7 @@ static void handle_records (ZOOM_connection c, Z_Records *sr, for (i = 0; inum_records; i++) { record_cache_add (resultset, p->records[i], - i+ resultset->start, 0); + i+ resultset->start); } /* transfer our response to search_nmem .. we need it later */ nmem_transfer (resultset->odr->mem, nmem); @@ -1325,15 +1407,12 @@ static int send_sort (ZOOM_connection c) static int send_present (ZOOM_connection c) { - Z_APDU *apdu = zget_APDU(c->odr_out, Z_APDU_presentRequest); - Z_PresentRequest *req = apdu->u.presentRequest; + Z_APDU *apdu = 0; + Z_PresentRequest *req = 0; int i = 0; - const char *syntax = - ZOOM_options_get (c->options, "preferredRecordSyntax"); - const char *element = - ZOOM_options_get (c->options, "elementSetName"); - const char *schema = - ZOOM_options_get (c->options, "schema"); + const char *syntax = 0; + const char *elementSetName = 0; + const char *schema = 0; ZOOM_resultset resultset; if (!c->tasks) @@ -1358,6 +1437,10 @@ static int send_present (ZOOM_connection c) return 0; } + syntax = ZOOM_resultset_option_get (resultset, "preferredRecordSyntax"); + elementSetName = ZOOM_resultset_option_get (resultset, "elementSetName"); + schema = ZOOM_resultset_option_get (resultset, "schema"); + if (c->error) /* don't continue on error */ return 0; if (resultset->start < 0) @@ -1365,13 +1448,16 @@ static int send_present (ZOOM_connection c) for (i = 0; icount; i++) { ZOOM_record rec = - record_cache_lookup (resultset, i + resultset->start, 0); + record_cache_lookup (resultset, i + resultset->start); if (!rec) break; } if (i == resultset->count) return 0; + apdu = zget_APDU(c->odr_out, Z_APDU_presentRequest); + req = apdu->u.presentRequest; + resultset->start += i; resultset->count -= i; *req->resultSetStartPoint = resultset->start + 1; @@ -1408,14 +1494,14 @@ static int send_present (ZOOM_connection c) compo->u.complex->generic->schema = (Odr_oid *) yaz_str_to_z3950oid (c->odr_out, CLASS_RECSYN, schema); } - if (element && *element) + if (elementSetName && *elementSetName) { compo->u.complex->generic->elementSpec = (Z_ElementSpec *) odr_malloc(c->odr_out, sizeof(Z_ElementSpec)); compo->u.complex->generic->elementSpec->which = Z_ElementSpec_elementSetName; compo->u.complex->generic->elementSpec->u.elementSetName = - odr_strdup (c->odr_out, element); + odr_strdup (c->odr_out, elementSetName); } else compo->u.complex->generic->elementSpec = 0; @@ -1424,7 +1510,7 @@ static int send_present (ZOOM_connection c) compo->u.complex->num_recordSyntax = 0; compo->u.complex->recordSyntax = 0; } - else if (element && *element) + else if (elementSetName && *elementSetName) { Z_ElementSetNames *esn = (Z_ElementSetNames *) odr_malloc (c->odr_out, sizeof(*esn)); @@ -1432,7 +1518,7 @@ static int send_present (ZOOM_connection c) odr_malloc (c->odr_out, sizeof(*compo)); esn->which = Z_ElementSetNames_generic; - esn->u.generic = odr_strdup (c->odr_out, element); + esn->u.generic = odr_strdup (c->odr_out, elementSetName); compo->which = Z_RecordComp_simple; compo->u.simple = esn; req->recordComposition = compo; @@ -1893,8 +1979,8 @@ static void handle_apdu (ZOOM_connection c, Z_APDU *apdu) { Z_InitResponse *initrs; - yaz_log (LOG_DEBUG, "hande_apdu type=%d", apdu->which); c->mask = 0; + yaz_log (LOG_DEBUG, "hande_apdu type=%d", apdu->which); switch(apdu->which) { case Z_APDU_initResponse: @@ -1965,6 +2051,22 @@ static void handle_apdu (ZOOM_connection c, Z_APDU *apdu) es_response (c, apdu->u.extendedServicesResponse); ZOOM_connection_remove_task (c); break; + case Z_APDU_close: + if (c->reconnect_ok) + { + do_close(c); + c->tasks->running = 0; + ZOOM_connection_insert_task (c, ZOOM_TASK_CONNECT); + } + else + { + c->error = ZOOM_ERROR_CONNECTION_LOST; + do_close(c); + } + break; + default: + c->error = ZOOM_ERROR_DECODE; + do_close(c); } } @@ -2001,7 +2103,6 @@ static int do_read (ZOOM_connection 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); @@ -2012,9 +2113,8 @@ static int do_read (ZOOM_connection c) do_close (c); } else - { handle_apdu (c, apdu); - } + c->reconnect_ok = 0; } return 1; } @@ -2224,6 +2324,7 @@ ZOOM_connection_last_event(ZOOM_connection cs) ZOOM_API(int) ZOOM_event (int no, ZOOM_connection *cs) { + int timeout = 5000; #if HAVE_SYS_POLL_H struct pollfd pollfds[1024]; ZOOM_connection poll_cs[1024]; @@ -2260,9 +2361,6 @@ ZOOM_event (int no, ZOOM_connection *cs) #if HAVE_SYS_POLL_H #else - tv.tv_sec = 15; - tv.tv_usec = 0; - FD_ZERO (&input); FD_ZERO (&output); FD_ZERO (&except); @@ -2272,6 +2370,7 @@ ZOOM_event (int no, ZOOM_connection *cs) { ZOOM_connection c = cs[i]; int fd, mask; + int this_timeout; if (!c) continue; @@ -2283,6 +2382,9 @@ ZOOM_event (int no, ZOOM_connection *cs) if (max_fd < fd) max_fd = fd; + this_timeout = ZOOM_options_get_int (c->options, "timeout", -1); + if (this_timeout != -1 && this_timeout < timeout) + timeout = this_timeout; #if HAVE_SYS_POLL_H if (mask) { @@ -2318,10 +2420,14 @@ ZOOM_event (int no, ZOOM_connection *cs) } #endif } + if (timeout >= 5000) + timeout = 30; + if (!nfds) return 0; + #if HAVE_SYS_POLL_H - r = poll (pollfds, nfds, 15000); + r = poll (pollfds, nfds, timeout * 1000); for (i = 0; i