X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fzoom-c.c;h=19947c39fd48789ffbfa46f0d0f1d9fe88d5d938;hp=492c19052c59d75090bf8088330b708bb1a1244a;hb=23794062255aca1313eaff359edb7b73a5f1a742;hpb=8d92137c228ec24df2d62a8039635bb8ad19558d diff --git a/src/zoom-c.c b/src/zoom-c.c index 492c190..19947c3 100644 --- a/src/zoom-c.c +++ b/src/zoom-c.c @@ -2,7 +2,7 @@ * Copyright (c) 2000-2003, Index Data * See the file LICENSE for details. * - * $Id: zoom-c.c,v 1.4 2003-11-19 19:07:26 adam Exp $ + * $Id: zoom-c.c,v 1.8 2003-11-26 16:22:35 mike Exp $ * * ZOOM layer for C, connections, result sets, queries. */ @@ -544,7 +544,12 @@ ZOOM_connection_search(ZOOM_connection c, ZOOM_query q) r->start = ZOOM_options_get_int(r->options, "start", 0); r->count = ZOOM_options_get_int(r->options, "count", 0); - r->step = ZOOM_options_get_int(r->options, "step", 0); + { + /* If "presentChunk" is defined use that; otherwise "step" */ + const char *cp = ZOOM_options_get (r->options, "presentChunk"); + r->step = ZOOM_options_get_int(r->options, + (cp != 0 ? "presentChunk": "step"), 0); + } r->piggyback = ZOOM_options_get_bool (r->options, "piggyback", 1); cp = ZOOM_options_get (r->options, "setname"); if (cp) @@ -892,7 +897,8 @@ static zoom_ret ZOOM_connection_send_init (ZOOM_connection c) const char *auth_groupId = ZOOM_options_get (c->options, "group"); const char *auth_userId = ZOOM_options_get (c->options, "user"); const char *auth_password = ZOOM_options_get (c->options, "pass"); - + char *version; + ODR_MASK_SET(ireq->options, Z_Options_search); ODR_MASK_SET(ireq->options, Z_Options_present); ODR_MASK_SET(ireq->options, Z_Options_scan); @@ -903,40 +909,22 @@ static zoom_ret ZOOM_connection_send_init (ZOOM_connection c) ODR_MASK_SET(ireq->protocolVersion, Z_ProtocolVersion_1); ODR_MASK_SET(ireq->protocolVersion, Z_ProtocolVersion_2); ODR_MASK_SET(ireq->protocolVersion, Z_ProtocolVersion_3); - - impid = ZOOM_options_get (c->options, "implementationId"); - ireq->implementationId = - (char *) odr_malloc (c->odr_out, 15 + (impid ? strlen(impid) : 0)); - strcpy (ireq->implementationId, ""); - if (impid) - { - strcat (ireq->implementationId, impid); - strcat (ireq->implementationId, "/"); - } - strcat (ireq->implementationId, "81"); /* Index's implementor ID */ - - impname = ZOOM_options_get (c->options, "implementationName"); - ireq->implementationName = - (char *) odr_malloc (c->odr_out, 15 + (impname ? strlen(impname) : 0)); - strcpy (ireq->implementationName, ""); - if (impname) - { - strcat (ireq->implementationName, impname); - strcat (ireq->implementationName, "/"); - } - strcat (ireq->implementationName, "ZOOM-C/YAZ"); - - impver = ZOOM_options_get (c->options, "implementationVersion"); - ireq->implementationVersion = - (char *) odr_malloc (c->odr_out, strlen("$Revision: 1.4 $") + 2 + - (impver ? strlen(impver) : 0)); - strcpy (ireq->implementationVersion, ""); - if (impver) - { - strcat (ireq->implementationVersion, impver); - strcat (ireq->implementationVersion, "/"); - } - strcat (ireq->implementationVersion, "$Revision: 1.4 $"); + + /* Index Data's Z39.50 Implementor Id is 81 */ + ireq->implementationId = odr_prepend(c->odr_out, + ZOOM_options_get(c->options, "implementationId"), + odr_prepend(c->odr_out, "81", ireq->implementationId)); + + ireq->implementationName = odr_prepend(c->odr_out, + ZOOM_options_get(c->options, "implementationName"), + odr_prepend(c->odr_out, "ZOOM-C", ireq->implementationName)); + + version = odr_strdup(c->odr_out, "$Revision: 1.8 $"); + if (strlen(version) > 10) /* check for unexpanded CVS strings */ + version[strlen(version)-2] = '\0'; + ireq->implementationVersion = odr_prepend(c->odr_out, + ZOOM_options_get(c->options, "implementationVersion"), + odr_prepend(c->odr_out, &version[10], ireq->implementationVersion)); *ireq->maximumRecordSize = ZOOM_options_get_int (c->options, "maximumRecordSize", 1024*1024); @@ -1504,8 +1492,11 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len) *len = strlen(desc); return desc; } - else if (!strcmp (type, "render") && - npr->which == Z_NamePlusRecord_databaseRecord) + if (npr->which != Z_NamePlusRecord_databaseRecord) + return 0; + + /* from now on - we have a database record .. */ + if (!strcmp (type, "render")) { Z_External *r = (Z_External *) npr->u.databaseRecord; oident *ent = oid_getentbyoid(r->direct_reference); @@ -1571,8 +1562,7 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len) } return 0; } - else if (npr->which == Z_NamePlusRecord_databaseRecord && - (!strcmp (type, "xml") || !strcmp(type, "oai"))) + else if (!strcmp (type, "xml") || !strcmp(type, "oai")) { Z_External *r = (Z_External *) npr->u.databaseRecord; oident *ent = oid_getentbyoid(r->direct_reference); @@ -1641,36 +1631,31 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, 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) { - 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, OPAC, ... */ - { - if (len) *len = -1; - return (const char *) npr->u.databaseRecord; - } + 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, OPAC, ... */ + { + 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; + if (len) *len = -1; + return (const char *) npr->u.databaseRecord; } - else if (npr->which == Z_NamePlusRecord_databaseRecord && - !strcmp (type, "opac")) + else if (!strcmp (type, "opac")) { Z_External *r = (Z_External *) npr->u.databaseRecord; @@ -2363,6 +2348,167 @@ static Z_ItemOrder *encode_item_order(ZOOM_package p) return req; } +Z_APDU *create_admin_package(ZOOM_package p, int type, + Z_ESAdminOriginPartToKeep **toKeepP, + Z_ESAdminOriginPartNotToKeep **notToKeepP) +{ + Z_APDU *apdu = create_es_package (p, VAL_ADMINSERVICE); + if (apdu) + { + Z_ESAdminOriginPartToKeep *toKeep; + Z_ESAdminOriginPartNotToKeep *notToKeep; + Z_External *r = (Z_External *) odr_malloc (p->odr_out, sizeof(*r)); + const char *first_db = "Default"; + int num_db; + char **db = set_DatabaseNames(p->connection, p->options, &num_db); + if (num_db > 0) + first_db = db[0]; + + r->direct_reference = + yaz_oidval_to_z3950oid(p->odr_out, CLASS_EXTSERV, + VAL_ADMINSERVICE); + r->descriptor = 0; + r->indirect_reference = 0; + r->which = Z_External_ESAdmin; + + r->u.adminService = (Z_Admin *) + odr_malloc(p->odr_out, sizeof(*r->u.adminService)); + r->u.adminService->which = Z_Admin_esRequest; + r->u.adminService->u.esRequest = (Z_AdminEsRequest *) + odr_malloc(p->odr_out, sizeof(*r->u.adminService->u.esRequest)); + + toKeep = r->u.adminService->u.esRequest->toKeep = + (Z_ESAdminOriginPartToKeep *) + odr_malloc(p->odr_out, sizeof(*r->u.adminService->u.esRequest->toKeep)); + toKeep->which=type; + toKeep->databaseName = odr_strdup(p->odr_out, first_db); + toKeep->u.create=odr_nullval(); + apdu->u.extendedServicesRequest->taskSpecificParameters = r; + + r->u.adminService->u.esRequest->notToKeep = notToKeep = + (Z_ESAdminOriginPartNotToKeep *) + odr_malloc(p->odr_out, + sizeof(*r->u.adminService->u.esRequest->notToKeep)); + notToKeep->which=Z_ESAdminOriginPartNotToKeep_recordsWillFollow; + notToKeep->u.recordsWillFollow=odr_nullval(); + if (toKeepP) + *toKeepP = toKeep; + if (notToKeepP) + *notToKeepP = notToKeep; + } + return apdu; +} + +static Z_APDU *create_update_package(ZOOM_package p) +{ + Z_APDU *apdu = 0; + const char *first_db = "Default"; + int num_db; + char **db = set_DatabaseNames(p->connection, p->options, &num_db); + const char *action = ZOOM_options_get(p->options, "action"); + const char *recordId = ZOOM_options_get(p->options, "recordId"); + const char *record_buf = ZOOM_options_get(p->options, "record"); + const char *syntax_str = ZOOM_options_get(p->options, "syntax"); + int syntax_oid = VAL_NONE; + int action_no = -1; + + if (syntax_str) + syntax_oid = oid_getvalbyname(syntax_str); + if (!record_buf) + { + record_buf = "void"; + syntax_oid = VAL_SUTRS; + } + if (syntax_oid != VAL_NONE) + syntax_oid = VAL_TEXT_XML; + + if (num_db > 0) + first_db = db[0]; + + if (!action) + action = "specialUpdate"; + + if (!strcmp(action, "recordInsert")) + action_no = Z_IUOriginPartToKeep_recordInsert; + else if (!strcmp(action, "recordReplace")) + action_no = Z_IUOriginPartToKeep_recordReplace; + else if (!strcmp(action, "recordDelete")) + action_no = Z_IUOriginPartToKeep_recordDelete; + else if (!strcmp(action, "elementUpdate")) + action_no = Z_IUOriginPartToKeep_elementUpdate; + else if (!strcmp(action, "specialUpdate")) + action_no = Z_IUOriginPartToKeep_specialUpdate; + else + return 0; + + apdu = create_es_package (p, VAL_DBUPDATE); + if (apdu) + { + Z_IUOriginPartToKeep *toKeep; + Z_IUSuppliedRecords *notToKeep; + Z_External *r = (Z_External *) + odr_malloc (p->odr_out, sizeof(*r)); + + apdu->u.extendedServicesRequest->taskSpecificParameters = r; + + r->direct_reference = + yaz_oidval_to_z3950oid(p->odr_out, CLASS_EXTSERV, + VAL_DBUPDATE); + r->descriptor = 0; + r->which = Z_External_update; + r->indirect_reference = 0; + r->u.update = (Z_IUUpdate *) + odr_malloc(p->odr_out, sizeof(*r->u.update)); + + r->u.update->which = Z_IUUpdate_esRequest; + r->u.update->u.esRequest = (Z_IUUpdateEsRequest *) + odr_malloc(p->odr_out, sizeof(*r->u.update->u.esRequest)); + toKeep = r->u.update->u.esRequest->toKeep = + (Z_IUOriginPartToKeep *) + odr_malloc(p->odr_out, sizeof(*toKeep)); + + toKeep->databaseName = odr_strdup(p->odr_out, first_db); + toKeep->schema = 0; + toKeep->elementSetName = 0; + toKeep->actionQualifier = 0; + toKeep->action = odr_intdup(p->odr_out, action_no); + + notToKeep = r->u.update->u.esRequest->notToKeep = + (Z_IUSuppliedRecords *) + odr_malloc(p->odr_out, sizeof(*notToKeep)); + notToKeep->num = 1; + notToKeep->elements = (Z_IUSuppliedRecords_elem **) + odr_malloc(p->odr_out, sizeof(*notToKeep->elements)); + notToKeep->elements[0] = (Z_IUSuppliedRecords_elem *) + odr_malloc(p->odr_out, sizeof(**notToKeep->elements)); + notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque; + if (recordId) + { + notToKeep->elements[0]->u.opaque = (Odr_oct *) + odr_malloc (p->odr_out, sizeof(Odr_oct)); + notToKeep->elements[0]->u.opaque->size = strlen(recordId); + notToKeep->elements[0]->u.opaque->len = strlen(recordId); + notToKeep->elements[0]->u.opaque->buf = + odr_strdup(p->odr_out, recordId); + } + else + notToKeep->elements[0]->u.opaque = 0; + notToKeep->elements[0]->supplementalId = 0; + notToKeep->elements[0]->correlationInfo = 0; + notToKeep->elements[0]->record = + z_ext_record(p->odr_out, syntax_oid, + record_buf, strlen(record_buf)); + } + if (0 && apdu) + { + ODR print = odr_createmem(ODR_PRINT); + + z_APDU(print, &apdu, 0, 0); + odr_destroy(print); + } + return apdu; +} + ZOOM_API(void) ZOOM_package_send (ZOOM_package p, const char *type) { @@ -2376,11 +2522,10 @@ ZOOM_API(void) p->buf_out = 0; if (!strcmp(type, "itemorder")) { - Z_External *r; apdu = create_es_package (p, VAL_ITEMORDER); if (apdu) { - r = (Z_External *) odr_malloc (p->odr_out, sizeof(*r)); + Z_External *r = (Z_External *) odr_malloc (p->odr_out, sizeof(*r)); r->direct_reference = yaz_oidval_to_z3950oid(p->odr_out, CLASS_EXTSERV, @@ -2393,6 +2538,20 @@ ZOOM_API(void) apdu->u.extendedServicesRequest->taskSpecificParameters = r; } } + if (!strcmp(type, "create")) /* create database */ + { + apdu = create_admin_package(p, Z_ESAdminOriginPartToKeep_create, + 0, 0); + } + if (!strcmp(type, "drop")) /* drop database */ + { + apdu = create_admin_package(p, Z_ESAdminOriginPartToKeep_drop, + 0, 0); + } + if (!strcmp(type, "update")) /* update record(s) */ + { + apdu = create_update_package(p); + } if (apdu) { if (encode_APDU(p->connection, apdu, p->odr_out) == 0) @@ -2565,6 +2724,16 @@ static void handle_apdu (ZOOM_connection c, Z_APDU *apdu) { case Z_APDU_initResponse: initrs = apdu->u.initResponse; + ZOOM_connection_option_set(c, "serverImplementationId", + initrs->implementationId ? + initrs->implementationId : ""); + ZOOM_connection_option_set(c, "serverImplementationName", + initrs->implementationName ? + initrs->implementationName : ""); + ZOOM_connection_option_set(c, "serverImplementationVersion", + initrs->implementationVersion ? + initrs->implementationVersion : ""); + /* Set the three old options too, for old applications */ ZOOM_connection_option_set(c, "targetImplementationId", initrs->implementationId ? initrs->implementationId : ""); @@ -2809,7 +2978,6 @@ static int do_read (ZOOM_connection c) event = ZOOM_Event_create (ZOOM_EVENT_RECV_DATA); ZOOM_connection_put_event (c, event); - r = cs_get (c->cs, &c->buf_in, &c->len_in); more = cs_more(c->cs); yaz_log (LOG_DEBUG, "do_read len=%d more=%d", r, more); @@ -2843,7 +3011,13 @@ static int do_read (ZOOM_connection c) if (!z_GDU (c->odr_in, &gdu, 0, 0)) { - set_ZOOM_error(c, ZOOM_ERROR_DECODE, 0); + int x; + int err = odr_geterrorx(c->odr_in, &x); + char msg[60]; + const char *element = odr_getelement(c->odr_in); + sprintf (msg, "ODR code %d:%d element=%-20s", + err, x, element ? element : ""); + set_ZOOM_error(c, ZOOM_ERROR_DECODE, msg); do_close (c); } else if (gdu->which == Z_GDU_Z3950)