/*
- * Copyright (c) 2000-2003, Index Data
+ * Copyright (c) 2000-2004, Index Data
* See the file LICENSE for details.
*
- * $Id: zoom-c.c,v 1.3 2003-11-17 16:01:12 mike Exp $
+ * $Id: zoom-c.c,v 1.29 2004-08-02 10:06:34 adam Exp $
*
* ZOOM layer for C, connections, result sets, queries.
*/
const char *dset,
const char *addinfo, const char *addinfo2)
{
+ char *cp;
xfree (c->addinfo);
c->addinfo = 0;
c->error = error;
- c->diagset = dset;
+ if (!c->diagset || strcmp(dset, c->diagset))
+ {
+ xfree(c->diagset);
+ c->diagset = xstrdup(dset);
+ /* remove integer part from SRW diagset .. */
+ if ((cp = strrchr(c->diagset, '/')))
+ *cp = '\0';
+ }
if (addinfo && addinfo2)
{
c->addinfo = xmalloc(strlen(addinfo) + strlen(addinfo2) + 2);
switch (task->which)
{
case ZOOM_TASK_SEARCH:
-
ZOOM_resultset_destroy (task->u.search.resultset);
break;
case ZOOM_TASK_RETRIEVE:
case ZOOM_TASK_PACKAGE:
ZOOM_package_destroy (task->u.package);
break;
+ case ZOOM_TASK_SORT:
+ ZOOM_resultset_destroy (task->u.sort.resultset);
+ ZOOM_query_destroy(task->u.sort.q);
+ break;
default:
assert (0);
}
c->reconnect_ok = 0;
c->state = STATE_IDLE;
c->addinfo = 0;
+ c->diagset = 0;
set_ZOOM_error(c, ZOOM_ERROR_NONE, 0);
c->buf_in = 0;
c->len_in = 0;
s->z_query->which = Z_Query_type_1;
s->z_query->u.type_1 = p_query_rpn(s->odr, PROTO_Z3950, str);
if (!s->z_query->u.type_1)
+ {
+ s->z_query = 0;
return -1;
+ }
return 0;
}
xfree (c->buf_in);
xfree (c->addinfo);
+ xfree (c->diagset);
odr_destroy (c->odr_in);
odr_destroy (c->odr_out);
ZOOM_options_destroy (c->options);
r, r->refcount);
}
}
+
ZOOM_resultset ZOOM_resultset_create ()
{
ZOOM_resultset r = (ZOOM_resultset) xmalloc (sizeof(*r));
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)
}
ZOOM_API(void)
+ ZOOM_resultset_sort(ZOOM_resultset r,
+ const char *sort_type, const char *sort_spec)
+{
+ ZOOM_connection c = r->connection;
+ ZOOM_task task;
+
+ if (!c)
+ return;
+
+ if (c->host_port && c->proto == PROTO_HTTP)
+ {
+ if (!c->cs)
+ {
+ yaz_log(LOG_DEBUG, "NO COMSTACK");
+ ZOOM_connection_add_task(c, ZOOM_TASK_CONNECT);
+ }
+ else
+ {
+ yaz_log(LOG_DEBUG, "PREPARE FOR RECONNECT");
+ c->reconnect_ok = 1;
+ }
+ }
+
+ ZOOM_resultset_cache_reset(r);
+ task = ZOOM_connection_add_task (c, ZOOM_TASK_SORT);
+ task->u.sort.resultset = r;
+ task->u.sort.q = ZOOM_query_create();
+ ZOOM_query_sortby(task->u.sort.q, sort_spec);
+
+ ZOOM_resultset_addref (r);
+
+ if (!c->async)
+ {
+ while (ZOOM_event (1, &c))
+ ;
+ }
+}
+
+ZOOM_API(void)
+ ZOOM_resultset_cache_reset(ZOOM_resultset r)
+{
+ ZOOM_record_cache rc;
+
+ for (rc = r->record_cache; rc; rc = rc->next)
+ {
+ if (rc->rec.wrbuf_marc)
+ wrbuf_free (rc->rec.wrbuf_marc, 1);
+ if (rc->rec.wrbuf_iconv)
+ wrbuf_free (rc->rec.wrbuf_iconv, 1);
+ if (rc->rec.wrbuf_opac)
+ wrbuf_free (rc->rec.wrbuf_opac, 1);
+ }
+ r->record_cache = 0;
+}
+
+ZOOM_API(void)
ZOOM_resultset_destroy(ZOOM_resultset r)
{
if (!r)
r, r->refcount);
if (r->refcount == 0)
{
- ZOOM_record_cache rc;
+ ZOOM_resultset_cache_reset(r);
- for (rc = r->record_cache; rc; rc = rc->next)
- {
- if (rc->rec.wrbuf_marc)
- wrbuf_free (rc->rec.wrbuf_marc, 1);
- if (rc->rec.wrbuf_iconv)
- wrbuf_free (rc->rec.wrbuf_iconv, 1);
- if (rc->rec.wrbuf_opac)
- wrbuf_free (rc->rec.wrbuf_opac, 1);
- }
if (r->connection)
{
/* remove ourselves from the resultsets in connection */
}
}
+static void get_cert(ZOOM_connection c)
+{
+ char *cert_buf;
+ int cert_len;
+
+ if (cs_get_peer_certificate_x509(c->cs, &cert_buf, &cert_len))
+ {
+ ZOOM_connection_option_setl(c, "sslPeerCert",
+ cert_buf, cert_len);
+ xfree(cert_buf);
+ }
+}
+
static zoom_ret do_connect (ZOOM_connection c)
{
void *add;
yaz_log (LOG_DEBUG, "do_connect host=%s", effective_host);
- assert (!c->cs);
+ if (c->cs)
+ cs_close(c->cs);
c->cs = cs_create_host (effective_host, 0, &add);
if (c->cs && c->cs->protocol == PROTO_HTTP)
{
ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_CONNECT);
ZOOM_connection_put_event(c, event);
+ get_cert(c);
if (c->proto == PROTO_Z3950)
ZOOM_connection_send_init(c);
else
static zoom_ret ZOOM_connection_send_init (ZOOM_connection c)
{
- const char *impid, *impname, *impver;
Z_APDU *apdu = zget_APDU(c->odr_out, Z_APDU_initRequest);
Z_InitRequest *ireq = apdu->u.initRequest;
Z_IdAuthentication *auth = (Z_IdAuthentication *)
odr_malloc(c->odr_out, sizeof(*auth));
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");
-
+ const char *auth_password = ZOOM_options_get (c->options, "password");
+ char *version;
+
+ /* support the pass for backwards compatibility */
+ if (!auth_password)
+ auth_password = ZOOM_options_get (c->options, "pass");
+
ODR_MASK_SET(ireq->options, Z_Options_search);
ODR_MASK_SET(ireq->options, Z_Options_present);
ODR_MASK_SET(ireq->options, Z_Options_scan);
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.3 $") + 2 +
- (impver ? strlen(impver) : 0));
- strcpy (ireq->implementationVersion, "");
- if (impver)
- {
- strcat (ireq->implementationVersion, impver);
- strcat (ireq->implementationVersion, "/");
- }
- strcat (ireq->implementationVersion, "$Revision: 1.3 $");
+
+ /* 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.29 $");
+ 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[11], ireq->implementationVersion));
*ireq->maximumRecordSize =
ZOOM_options_get_int (c->options, "maximumRecordSize", 1024*1024);
{
char ctype[50];
Z_SOAP_Handler h[2] = {
- {"http://www.loc.gov/zing/srw/v1.0/", 0, (Z_SOAP_fun) yaz_srw_codec},
+ {"http://www.loc.gov/zing/srw/", 0, (Z_SOAP_fun) yaz_srw_codec},
{0, 0, 0}
};
ODR o = odr_createmem(ODR_ENCODE);
/* prepare query for the search request */
search_req->query = r->query->z_query;
+ if (!search_req->query)
+ {
+ set_ZOOM_error(c, ZOOM_ERROR_INVALID_QUERY, 0);
+ return zoom_complete;
+ }
search_req->databaseNames =
set_DatabaseNames (c, r->options, &search_req->num_databaseNames);
xfree (rec);
}
+static const char *marc_iconv_return(ZOOM_record rec, int marc_type,
+ int *len,
+ const char *buf, int sz,
+ const char *record_charset)
+{
+ char to[40];
+ char from[40];
+ yaz_iconv_t cd = 0;
+ yaz_marc_t mt = yaz_marc_create();
+
+ *from = '\0';
+ strcpy(to, "UTF-8");
+ if (record_charset && *record_charset)
+ {
+ /* Use "from,to" or just "from" */
+ const char *cp =strchr(record_charset, ',');
+ int clen = strlen(record_charset);
+ if (cp && cp[1])
+ {
+ strncpy( to, cp+1, sizeof(to)-1);
+ to[sizeof(to)-1] = '\0';
+ clen = cp - record_charset;
+ }
+ if (clen > sizeof(from)-1)
+ clen = sizeof(from)-1;
+
+ if (clen)
+ strncpy(from, record_charset, clen);
+ from[clen] = '\0';
+ }
+
+ if (*from && *to)
+ {
+ cd = yaz_iconv_open(to, from);
+ yaz_marc_iconv(mt, cd);
+ }
+
+ yaz_marc_xml(mt, marc_type);
+ if (!rec->wrbuf_marc)
+ rec->wrbuf_marc = wrbuf_alloc();
+ wrbuf_rewind (rec->wrbuf_marc);
+ if (yaz_marc_decode_wrbuf (mt, buf, sz, rec->wrbuf_marc) > 0)
+ {
+ yaz_marc_destroy(mt);
+ if (cd)
+ yaz_iconv_close(cd);
+ if (len)
+ *len = wrbuf_len(rec->wrbuf_marc);
+ return wrbuf_buf(rec->wrbuf_marc);
+ }
+ yaz_marc_destroy(mt);
+ if (cd)
+ yaz_iconv_close(cd);
+ return 0;
+}
+
static const char *record_iconv_return(ZOOM_record rec, int *len,
const char *buf, int sz,
const char *record_charset)
{
char type[40];
char charset[40];
+ char xpath[512];
const char *cp;
int i;
Z_NamePlusRecord *npr;
}
type[i] = '\0';
charset[0] = '\0';
- if (type_spec[i] == ';')
+ while (type_spec[i] == ';')
{
i++;
while (type_spec[i] == ' ')
i++;
if (!strncmp(type_spec+i, "charset=", 8))
{
- cp = type_spec+i+8;
- for (i = 0; cp[i] && i < sizeof(charset)-1; i++)
+ int j = 0;
+ i = i + 8; /* skip charset= */
+ for (j = 0; type_spec[i] && j < sizeof(charset)-1; i++, j++)
{
- if (cp[i] == ';' || cp[i] == ' ')
+ if (type_spec[i] == ';' || type_spec[i] == ' ')
break;
- charset[i] = cp[i];
+ charset[j] = cp[i];
}
- charset[i] = '\0';
+ charset[j] = '\0';
}
- }
-
+ else if (!strncmp(type_spec+i, "xpath=", 6))
+ {
+ int j = 0;
+ i = i + 6;
+ for (j = 0; type_spec[i] && j < sizeof(xpath)-1; i++, j++)
+ xpath[j] = cp[i];
+ xpath[j] = '\0';
+ }
+ while (type_spec[i] == ' ')
+ i++;
+ }
if (!strcmp (type, "database"))
{
if (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);
charset);
else if (r->which == Z_External_octet)
{
- yaz_marc_t mt;
+ const char *ret_buf;
switch (ent->value)
{
case VAL_SOIF:
case VAL_APPLICATION_XML:
break;
default:
- if (!rec->wrbuf_marc)
- rec->wrbuf_marc = wrbuf_alloc();
-
- mt = yaz_marc_create();
- wrbuf_rewind (rec->wrbuf_marc);
- if (yaz_marc_decode_wrbuf (
- mt, (const char *) r->u.octet_aligned->buf,
- r->u.octet_aligned->len,
- rec->wrbuf_marc) > 0)
- {
- yaz_marc_destroy(mt);
- return record_iconv_return(rec, len,
- wrbuf_buf(rec->wrbuf_marc),
- wrbuf_len(rec->wrbuf_marc),
- charset);
- }
- yaz_marc_destroy(mt);
+ ret_buf = marc_iconv_return(
+ rec, YAZ_MARC_LINE, len,
+ (const char *) r->u.octet_aligned->buf,
+ r->u.octet_aligned->len,
+ charset);
+ if (ret_buf)
+ return ret_buf;
}
return record_iconv_return(rec, len,
(const char *) r->u.octet_aligned->buf,
}
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);
charset);
else if (r->which == Z_External_octet)
{
- yaz_marc_t mt;
+ const char *ret_buf;
int marc_decode_type = YAZ_MARC_MARCXML;
if (!strcmp(type, "oai"))
case VAL_APPLICATION_XML:
break;
default:
- if (!rec->wrbuf_marc)
- rec->wrbuf_marc = wrbuf_alloc();
- wrbuf_rewind (rec->wrbuf_marc);
- mt = yaz_marc_create();
-
- yaz_marc_xml(mt, YAZ_MARC_MARCXML);
- if (yaz_marc_decode_wrbuf (
- mt, (const char *) r->u.octet_aligned->buf,
- r->u.octet_aligned->len,
- rec->wrbuf_marc) > 0)
- {
- yaz_marc_destroy(mt);
- return record_iconv_return(rec, len,
- wrbuf_buf(rec->wrbuf_marc),
- wrbuf_len(rec->wrbuf_marc),
- charset);
- }
- yaz_marc_destroy(mt);
+ ret_buf = marc_iconv_return(
+ rec, marc_decode_type, len,
+ (const char *) r->u.octet_aligned->buf,
+ r->u.octet_aligned->len,
+ charset);
+ if (ret_buf)
+ return ret_buf;
}
return record_iconv_return(rec, len,
(const char *) r->u.octet_aligned->buf,
}
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;
return 1;
}
-static zoom_ret send_sort (ZOOM_connection c)
+static zoom_ret send_sort (ZOOM_connection c,
+ ZOOM_resultset resultset)
{
- ZOOM_resultset resultset;
-
- if (!c->tasks || c->tasks->which != ZOOM_TASK_SEARCH)
- return zoom_complete;
-
- resultset = c->tasks->u.search.resultset;
-
if (c->error)
- {
resultset->r_sort_spec = 0;
- return zoom_complete;
- }
if (resultset->r_sort_spec)
{
Z_APDU *apdu = zget_APDU(c->odr_out, Z_APDU_sortRequest);
ZOOM_API(const char *)
ZOOM_scanset_term (ZOOM_scanset scan, size_t pos,
- int *occ, int *len)
+ int *occ, int *len)
{
const char *term = 0;
size_t noent = ZOOM_scanset_size (scan);
}
ZOOM_API(const char *)
+ZOOM_scanset_display_term (ZOOM_scanset scan, size_t pos,
+ int *occ, int *len)
+{
+ const char *term = 0;
+ size_t noent = ZOOM_scanset_size (scan);
+ Z_ScanResponse *res = scan->scan_response;
+
+ *len = 0;
+ *occ = 0;
+ if (pos >= noent)
+ return 0;
+ if (res->entries->entries[pos]->which == Z_Entry_termInfo)
+ {
+ Z_TermInfo *t = res->entries->entries[pos]->u.termInfo;
+
+ if (t->displayTerm)
+ {
+ term = t->displayTerm;
+ *len = strlen(term);
+ }
+ else if (t->term->which == Z_Term_general)
+ {
+ term = (const char *) t->term->u.general->buf;
+ *len = t->term->u.general->len;
+ }
+ *occ = t->globalOccurrences ? *t->globalOccurrences : 0;
+ }
+ return term;
+}
+
+ZOOM_API(const char *)
ZOOM_scanset_option_get (ZOOM_scanset scan, const char *key)
{
return ZOOM_options_get (scan->options, key);
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 *recordIdOpaque = ZOOM_options_get(p->options, "recordIdOpaque");
+ const char *recordIdNumber = ZOOM_options_get(p->options, "recordIdNumber");
+ 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 (recordIdOpaque)
+ {
+ notToKeep->elements[0]->u.opaque = (Odr_oct *)
+ odr_malloc (p->odr_out, sizeof(Odr_oct));
+ notToKeep->elements[0]->u.opaque->size =
+ notToKeep->elements[0]->u.opaque->len = strlen(recordIdOpaque);
+ notToKeep->elements[0]->u.opaque->buf =
+ odr_strdup(p->odr_out, recordIdOpaque);
+ }
+ else if (recordIdNumber)
+ {
+ notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_number;
+
+ notToKeep->elements[0]->u.number =
+ odr_intdup(p->odr_out, atoi(recordIdNumber));
+ }
+ 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)
{
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,
apdu->u.extendedServicesRequest->taskSpecificParameters = r;
}
}
+ else if (!strcmp(type, "create")) /* create database */
+ {
+ apdu = create_admin_package(p, Z_ESAdminOriginPartToKeep_create,
+ 0, 0);
+ }
+ else if (!strcmp(type, "drop")) /* drop database */
+ {
+ apdu = create_admin_package(p, Z_ESAdminOriginPartToKeep_drop,
+ 0, 0);
+ }
+ else if (!strcmp(type, "commit")) /* commit changes */
+ {
+ apdu = create_admin_package(p, Z_ESAdminOriginPartToKeep_commit,
+ 0, 0);
+ }
+ else if (!strcmp(type, "update")) /* update record(s) */
+ {
+ apdu = create_update_package(p);
+ }
if (apdu)
{
if (encode_APDU(p->connection, apdu, p->odr_out) == 0)
break;
case ZOOM_TASK_PACKAGE:
ret = send_package(c);
+ break;
+ case ZOOM_TASK_SORT:
+ c->tasks->u.sort.resultset->r_sort_spec =
+ c->tasks->u.sort.q->sort_spec;
+ ret = send_sort(c, c->tasks->u.sort.resultset);
break;
}
}
static zoom_ret send_sort_present (ZOOM_connection c)
{
- zoom_ret r = send_sort (c);
+ zoom_ret r = zoom_complete;
+
+ if (c->tasks && c->tasks->which == ZOOM_TASK_SEARCH)
+ r = send_sort (c, c->tasks->u.search.resultset);
if (r == zoom_complete)
r = send_present (c);
return r;
{
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 : "");
}
if (res->num_diagnostics > 0)
{
- set_dset_error(c, *res->diagnostics[0].code, "SRW",
- res->diagnostics[0].details, 0);
+ const char *uri = res->diagnostics[0].uri;
+ if (uri)
+ {
+ int code = 0;
+ const char *cp;
+ if ((cp = strrchr(uri, '/')))
+ code = atoi(cp+1);
+ set_dset_error(c, code, uri,
+ res->diagnostics[0].details, 0);
+ }
}
nmem = odr_extract_mem(c->odr_in);
nmem_transfer(resultset->odr->mem, nmem);
if (content_type && !yaz_strcmp_del("text/xml", content_type, "; "))
{
Z_SOAP *soap_package = 0;
- ODR o = odr_createmem(ODR_DECODE);
+ ODR o = c->odr_in;
Z_SOAP_Handler soap_handlers[2] = {
- {"http://www.loc.gov/zing/srw/v1.0/", 0,
+ {"http://www.loc.gov/zing/srw/", 0,
(Z_SOAP_fun) yaz_srw_codec},
{0, 0, 0}
};
}
else
ret = -1;
- odr_destroy(o);
}
if (ret)
{
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);
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 : "<unknown>");
+ set_ZOOM_error(c, ZOOM_ERROR_DECODE, msg);
do_close (c);
}
else if (gdu->which == Z_GDU_Z3950)
ZOOM_API(void)
ZOOM_connection_option_set (ZOOM_connection c, const char *key,
- const char *val)
+ const char *val)
{
ZOOM_options_set (c->options, key, val);
}
+ZOOM_API(void)
+ZOOM_connection_option_setl (ZOOM_connection c, const char *key,
+ const char *val, int len)
+{
+ ZOOM_options_setl (c->options, key, val, len);
+}
+
ZOOM_API(const char *)
ZOOM_resultset_option_get (ZOOM_resultset r, const char *key)
{
return "Unsupported protocol";
case ZOOM_ERROR_UNSUPPORTED_QUERY:
return "Unsupported query type";
+ case ZOOM_ERROR_INVALID_QUERY:
+ return "Invalid query";
default:
return diagbib1_str (error);
}
*cp = z_HTTP_errmsg(c->error);
else if (!strcmp(c->diagset, "Bib-1"))
*cp = ZOOM_diag_str(error);
- else if (!strcmp(c->diagset, "SRW"))
+ else if (!strcmp(c->diagset, "info:srw/diagnostic/1"))
*cp = yaz_diag_srw_str(c->error);
else
*cp = "Unknown error and diagnostic set";
else if (ret == 0)
{
ZOOM_connection_put_event (c, event);
+ get_cert(c);
if (c->proto == PROTO_Z3950)
ZOOM_connection_send_init(c);
else