* Copyright (C) 1995-2007, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: zoom-c.c,v 1.128 2007-05-05 11:55:22 adam Exp $
+ * $Id: zoom-c.c,v 1.139 2007-07-04 11:42:14 adam Exp $
*/
/**
* \file zoom-c.c
#include <yaz/ccl.h>
#include <yaz/query-charset.h>
#include <yaz/copy_types.h>
+#include <yaz/snprintf.h>
static int log_api = 0;
static int log_details = 0;
* This wrapper is just for logging failed lookups. It would be nicer
* if it could cause failure when a lookup fails, but that's hard.
*/
-static int *zoom_yaz_str_to_z3950oid(ZOOM_connection c,
+static Odr_oid *zoom_yaz_str_to_z3950oid(ZOOM_connection c,
int oid_class, const char *str) {
- int *res = yaz_string_to_oid_odr(yaz_oid_std(), oid_class, str,
+ Odr_oid *res = yaz_string_to_oid_odr(yaz_oid_std(), oid_class, str,
c->odr_out);
if (res == 0)
yaz_log(YLOG_WARN, "%p OID lookup (%d, '%s') failed",
for (i = 0; i<200; i++)
{
size_t len;
- int *oid;
+ Odr_oid *oid;
Z_OtherInformation **oi;
char buf[80];
const char *val;
odr_prepend(c->odr_out, "ZOOM-C",
ireq->implementationName));
- version = odr_strdup(c->odr_out, "$Revision: 1.128 $");
+ version = odr_strdup(c->odr_out, "$Revision: 1.139 $");
if (strlen(version) > 10) /* check for unexpanded CVS strings */
version[strlen(version)-2] = '\0';
ireq->implementationVersion =
static void response_default_diag(ZOOM_connection c, Z_DefaultDiagFormat *r)
{
- int oclass;
+ char oid_name_buf[OID_STR_MAX];
+ const char *oid_name;
char *addinfo = 0;
+ oid_name = yaz_oid_to_string_buf(r->diagnosticSetId, 0, oid_name_buf);
switch (r->which)
{
case Z_DefaultDiagFormat_v2Addinfo:
}
xfree(c->addinfo);
c->addinfo = 0;
- set_dset_error(c, *r->condition,
- yaz_oid_to_string(yaz_oid_std(),
- r->diagnosticSetId, &oclass),
- addinfo, 0);
+ set_dset_error(c, *r->condition, oid_name, addinfo, 0);
}
static void response_diag(ZOOM_connection c, Z_DiagRec *p)
if (diag_rec->which == Z_DiagRec_defaultFormat)
{
Z_DefaultDiagFormat *ddf = diag_rec->u.defaultFormat;
- int oclass;
+ oid_class oclass;
error = *ddf->condition;
switch (ddf->which)
if (!strcmp(type, "render"))
{
Z_External *r = (Z_External *) npr->u.databaseRecord;
- const int *oid = r->direct_reference;
+ const Odr_oid *oid = r->direct_reference;
/* render bibliographic record .. */
if (r->which == Z_External_OPAC)
else if (!strcmp(type, "xml"))
{
Z_External *r = (Z_External *) npr->u.databaseRecord;
- const int *oid = r->direct_reference;
+ const Odr_oid *oid = r->direct_reference;
/* render bibliographic record .. */
if (r->which == Z_External_OPAC)
ZOOM_options_set(scan->options, key, val);
}
-static Z_APDU *create_es_package(ZOOM_package p, const int *oid)
+static Z_APDU *create_es_package(ZOOM_package p, const Odr_oid *oid)
{
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 = odr_strdup(p->odr_out, str);
if (str)
{
if (!strcmp (str, "create"))
- *req->function = 1;
+ *req->function = Z_ExtendedServicesRequest_create;
if (!strcmp (str, "delete"))
- *req->function = 2;
+ *req->function = Z_ExtendedServicesRequest_delete;
if (!strcmp (str, "modify"))
- *req->function = 3;
+ *req->function = Z_ExtendedServicesRequest_modify;
+ }
+
+ str = ZOOM_options_get(p->options, "waitAction");
+ if (str)
+ {
+ if (!strcmp (str, "wait"))
+ *req->waitAction = Z_ExtendedServicesRequest_wait;
+ if (!strcmp (str, "waitIfPossible"))
+ *req->waitAction = Z_ExtendedServicesRequest_waitIfPossible;
+ if (!strcmp (str, "dontWait"))
+ *req->waitAction = Z_ExtendedServicesRequest_dontWait;
+ if (!strcmp (str, "dontReturnPackage"))
+ *req->waitAction = Z_ExtendedServicesRequest_dontReturnPackage;
}
return apdu;
}
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");
+ const char *version = ZOOM_options_get(p->options, "updateVersion");
+
+ const char *correlationInfo_note =
+ ZOOM_options_get(p->options, "correlationInfo.note");
+ const char *correlationInfo_id =
+ ZOOM_options_get(p->options, "correlationInfo.id");
int action_no = -1;
- int *syntax_oid = 0;
+ Odr_oid *syntax_oid = 0;
+ const Odr_oid *package_oid = yaz_oid_extserv_database_update;
+ if (!version)
+ version = "3";
if (!syntax_str)
syntax_str = "xml";
if (!record_buf)
if (num_db > 0)
first_db = db[0];
- if (!action)
- action = "specialUpdate";
+ switch(*version)
+ {
+ case '1':
+ package_oid = yaz_oid_extserv_database_update_first_version;
+ /* old update does not support specialUpdate */
+ if (!action)
+ action = "recordInsert";
+ break;
+ case '2':
+ if (!action)
+ action = "specialUpdate";
+ package_oid = yaz_oid_extserv_database_update_second_version;
+ break;
+ case '3':
+ if (!action)
+ action = "specialUpdate";
+ package_oid = yaz_oid_extserv_database_update;
+ break;
+ default:
+ return 0;
+ }
if (!strcmp(action, "recordInsert"))
action_no = Z_IUOriginPartToKeep_recordInsert;
else
return 0;
- apdu = create_es_package(p, yaz_oid_extserv_database_update);
+ apdu = create_es_package(p, package_oid);
if (apdu)
{
Z_IUOriginPartToKeep *toKeep;
Z_IUSuppliedRecords *notToKeep;
Z_External *r = (Z_External *)
odr_malloc(p->odr_out, sizeof(*r));
+ const char *elementSetName =
+ ZOOM_options_get(p->options, "elementSetName");
apdu->u.extendedServicesRequest->taskSpecificParameters = r;
-
- r->direct_reference = odr_oiddup(p->odr_out,
- yaz_oid_extserv_database_update);
+ r->direct_reference = odr_oiddup(p->odr_out, package_oid);
r->descriptor = 0;
r->which = Z_External_update;
r->indirect_reference = 0;
toKeep->databaseName = odr_strdup(p->odr_out, first_db);
toKeep->schema = 0;
+
toKeep->elementSetName = 0;
+ if (elementSetName)
+ toKeep->elementSetName = odr_strdup(p->odr_out, elementSetName);
+
toKeep->actionQualifier = 0;
toKeep->action = odr_intdup(p->odr_out, action_no);
else
notToKeep->elements[0]->u.opaque = 0;
notToKeep->elements[0]->supplementalId = 0;
- notToKeep->elements[0]->correlationInfo = 0;
+ if (correlationInfo_note || correlationInfo_id)
+ {
+ Z_IUCorrelationInfo *ci;
+ ci = notToKeep->elements[0]->correlationInfo =
+ odr_malloc(p->odr_out, sizeof(*ci));
+ ci->note = correlationInfo_note ?
+ odr_strdup(p->odr_out, correlationInfo_note) : 0;
+ ci->id = correlationInfo_id ?
+ odr_intdup(p->odr_out, atoi(correlationInfo_id)) : 0;
+ }
+ else
+ notToKeep->elements[0]->correlationInfo = 0;
notToKeep->elements[0]->record =
z_ext_record_oid(p->odr_out, syntax_oid,
record_buf, strlen(record_buf));
static void set_init_option(const char *name, void *clientData) {
- ZOOM_connection c = clientData;
+ ZOOM_connection c = (ZOOM_connection) clientData;
char buf[80];
sprintf(buf, "init_opt_%.70s", name);
switch(apdu->which)
{
case Z_APDU_initResponse:
- yaz_log(log_api, "%p recv_apd: Received Init response", c);
+ yaz_log(log_api, "%p recv_apdu: Received Init response", c);
initrs = apdu->u.initResponse;
ZOOM_connection_option_set(c, "serverImplementationId",
initrs->implementationId ?
static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres)
{
int ret = -1;
- const char *content_type = z_HTTP_header_lookup(hres->headers,
- "Content-Type");
+ const char *addinfo = 0;
const char *connection_head = z_HTTP_header_lookup(hres->headers,
"Connection");
ZOOM_connection_set_mask(c, 0);
yaz_log(log_details, "%p handle_http", c);
-
- if (content_type && !yaz_strcmp_del("text/xml", content_type, "; "))
+
+ if (!yaz_srw_check_content_type(hres))
+ addinfo = "content-type";
+ else
{
Z_SOAP *soap_package = 0;
ODR o = c->odr_in;
if (hres->code != 200)
set_HTTP_error(c, hres->code, 0, 0);
else
- set_ZOOM_error(c, ZOOM_ERROR_DECODE, 0);
+ set_ZOOM_error(c, ZOOM_ERROR_DECODE, addinfo);
do_close(c);
}
ZOOM_connection_remove_task(c);
{
int x;
int err = odr_geterrorx(c->odr_in, &x);
- char msg[60];
+ char msg[100];
const char *element = odr_getelement(c->odr_in);
- sprintf(msg, "ODR code %d:%d element=%-20s",
- err, x, element ? element : "<unknown>");
+ yaz_snprintf(msg, sizeof(msg),
+ "ODR code %d:%d element=%s offset=%d",
+ err, x, element ? element : "<unknown>",
+ odr_offset(c->odr_in));
set_ZOOM_error(c, ZOOM_ERROR_DECODE, msg);
+ if (log_api)
+ {
+ FILE *ber_file = yaz_log_file();
+ if (ber_file)
+ odr_dumpBER(ber_file, c->buf_in, r);
+ }
do_close(c);
}
else if (gdu->which == Z_GDU_Z3950)
if (c->cs->io_pending & CS_WANT_READ)
mask += ZOOM_SELECT_READ;
ZOOM_connection_set_mask(c, mask);
+ event = ZOOM_Event_create(ZOOM_EVENT_NONE);
+ ZOOM_connection_put_event(c, event);
}
else if (ret == 0)
{
static void cql2pqf_wrbuf_puts(const char *buf, void *client_data)
{
- WRBUF wrbuf = client_data;
+ WRBUF wrbuf = (WRBUF) client_data;
wrbuf_puts(wrbuf, buf);
}