+ if (parse_cmd_doc(&arg, out, &recid_buf, &recid_len) == 0)
+ {
+ printf("Missing recid\n");
+ return 0;
+ }
+
+ if (!strcmp(action_buf, "insert"))
+ action_no = Z_IUOriginPartToKeep_recordInsert;
+ else if (!strcmp(action_buf, "replace"))
+ action_no = Z_IUOriginPartToKeep_recordReplace;
+ else if (!strcmp(action_buf, "delete"))
+ action_no = Z_IUOriginPartToKeep_recordDelete;
+ else if (!strcmp(action_buf, "update"))
+ action_no = Z_IUOriginPartToKeep_specialUpdate;
+ else
+ {
+ printf("Bad action: %s\n", action_buf);
+ printf("Possible values: insert, replace, delete, update\n");
+ return 0;
+ }
+
+ if (strcmp(recid_buf, "none")) /* none means no record ID */
+ recid = recid_buf;
+
+ arg += noread;
+ if (parse_cmd_doc(&arg, out, &rec_buf, &rec_len) == 0)
+ return 0;
+
+#if YAZ_HAVE_XML2
+ if (protocol == PROTO_HTTP)
+ return cmd_update_SRW(action_no, recid_buf, rec_buf, rec_len);
+#endif
+ return cmd_update_Z3950(version, action_no, recid_buf, rec_buf, rec_len);
+}
+
+#if YAZ_HAVE_XML2
+static int cmd_update_SRW(int action_no, const char *recid,
+ char *rec_buf, int rec_len)
+{
+ if (!conn)
+ session_connect(cur_host);
+ if (!conn)
+ return 0;
+ else
+ {
+ Z_SRW_PDU *srw = yaz_srw_get(out, Z_SRW_update_request);
+ Z_SRW_updateRequest *sr = srw->u.update_request;
+
+ switch(action_no)
+ {
+ case Z_IUOriginPartToKeep_recordInsert:
+ sr->operation = "info:srw/action/1/create";
+ break;
+ case Z_IUOriginPartToKeep_recordReplace:
+ sr->operation = "info:srw/action/1/replace";
+ break;
+ case Z_IUOriginPartToKeep_recordDelete:
+ sr->operation = "info:srw/action/1/delete";
+ break;
+ }
+ if (rec_buf)
+ {
+ sr->record = yaz_srw_get_record(out);
+ sr->record->recordData_buf = rec_buf;
+ sr->record->recordData_len = rec_len;
+ sr->record->recordSchema = record_schema;
+ }
+ if (recid)
+ sr->recordId = odr_strdup(out, recid);
+ return send_srw(srw);
+ }
+}
+#endif
+
+static int cmd_update_Z3950(int version, int action_no, const char *recid,
+ char *rec_buf, int rec_len)
+{
+ Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest );
+ Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
+ Z_External *r;
+ Z_External *record_this = 0;
+ if (rec_buf)
+ record_this = z_ext_record_oid(out, yaz_oid_recsyn_xml,
+ rec_buf, rec_len);
+ else
+ {
+ if (!record_last)
+ {
+ printf("No last record (update ignored)\n");
+ return 0;
+ }
+ record_this = record_last;
+ }
+
+ req->packageType = odr_oiddup(out, (version == 0 ?
+ yaz_oid_extserv_database_update_first_version :
+ yaz_oid_extserv_database_update));
+
+ req->packageName = esPackageName;
+
+ req->referenceId = set_refid (out);
+
+ r = req->taskSpecificParameters = (Z_External *)
+ odr_malloc(out, sizeof(*r));
+ r->direct_reference = req->packageType;
+ r->indirect_reference = 0;
+ r->descriptor = 0;
+ if (version == 0)
+ {
+ Z_IU0OriginPartToKeep *toKeep;
+ Z_IU0SuppliedRecords *notToKeep;
+
+ r->which = Z_External_update0;
+ r->u.update0 = (Z_IU0Update *) odr_malloc(out, sizeof(*r->u.update0));
+ r->u.update0->which = Z_IUUpdate_esRequest;
+ r->u.update0->u.esRequest = (Z_IU0UpdateEsRequest *)
+ odr_malloc(out, sizeof(*r->u.update0->u.esRequest));
+ toKeep = r->u.update0->u.esRequest->toKeep = (Z_IU0OriginPartToKeep *)
+ odr_malloc(out, sizeof(*r->u.update0->u.esRequest->toKeep));
+
+ toKeep->databaseName = databaseNames[0];
+ toKeep->schema = 0;
+ if (record_schema)
+ {
+ toKeep->schema = yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_SCHEMA,
+ record_schema, out);
+ }
+ toKeep->elementSetName = 0;
+
+ toKeep->action = (int *) odr_malloc(out, sizeof(*toKeep->action));
+ *toKeep->action = action_no;
+
+ notToKeep = r->u.update0->u.esRequest->notToKeep = (Z_IU0SuppliedRecords *)
+ odr_malloc(out, sizeof(*r->u.update0->u.esRequest->notToKeep));
+ notToKeep->num = 1;
+ notToKeep->elements = (Z_IU0SuppliedRecords_elem **)
+ odr_malloc(out, sizeof(*notToKeep->elements));
+ notToKeep->elements[0] = (Z_IU0SuppliedRecords_elem *)
+ odr_malloc(out, sizeof(**notToKeep->elements));
+ notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque;
+ if (recid)
+ {
+ notToKeep->elements[0]->u.opaque = (Odr_oct *)
+ odr_malloc(out, sizeof(Odr_oct));
+ notToKeep->elements[0]->u.opaque->buf = (unsigned char *) recid;
+ notToKeep->elements[0]->u.opaque->size = strlen(recid);
+ notToKeep->elements[0]->u.opaque->len = strlen(recid);
+ }
+ else
+ notToKeep->elements[0]->u.opaque = 0;
+ notToKeep->elements[0]->supplementalId = 0;
+ notToKeep->elements[0]->correlationInfo = 0;
+ notToKeep->elements[0]->record = record_this;
+ }
+ else
+ {
+ Z_IUOriginPartToKeep *toKeep;
+ Z_IUSuppliedRecords *notToKeep;
+
+ r->which = Z_External_update;
+ r->u.update = (Z_IUUpdate *) odr_malloc(out, sizeof(*r->u.update));
+ r->u.update->which = Z_IUUpdate_esRequest;
+ r->u.update->u.esRequest = (Z_IUUpdateEsRequest *)
+ odr_malloc(out, sizeof(*r->u.update->u.esRequest));
+ toKeep = r->u.update->u.esRequest->toKeep = (Z_IUOriginPartToKeep *)
+ odr_malloc(out, sizeof(*r->u.update->u.esRequest->toKeep));
+
+ toKeep->databaseName = databaseNames[0];
+ toKeep->schema = 0;
+ if (record_schema)
+ {
+ toKeep->schema = yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_SCHEMA,
+ record_schema, out);
+ }
+ toKeep->elementSetName = 0;
+ toKeep->actionQualifier = 0;
+ toKeep->action = (int *) odr_malloc(out, sizeof(*toKeep->action));
+ *toKeep->action = action_no;
+
+ notToKeep = r->u.update->u.esRequest->notToKeep = (Z_IUSuppliedRecords *)
+ odr_malloc(out, sizeof(*r->u.update->u.esRequest->notToKeep));
+ notToKeep->num = 1;
+ notToKeep->elements = (Z_IUSuppliedRecords_elem **)
+ odr_malloc(out, sizeof(*notToKeep->elements));
+ notToKeep->elements[0] = (Z_IUSuppliedRecords_elem *)
+ odr_malloc(out, sizeof(**notToKeep->elements));
+ notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque;
+ if (recid)
+ {
+ notToKeep->elements[0]->u.opaque = (Odr_oct *)
+ odr_malloc(out, sizeof(Odr_oct));
+ notToKeep->elements[0]->u.opaque->buf = (unsigned char *) recid;
+ notToKeep->elements[0]->u.opaque->size = strlen(recid);
+ notToKeep->elements[0]->u.opaque->len = strlen(recid);
+ }
+ else
+ notToKeep->elements[0]->u.opaque = 0;
+ notToKeep->elements[0]->supplementalId = 0;
+ notToKeep->elements[0]->correlationInfo = 0;
+ notToKeep->elements[0]->record = record_this;
+ }
+
+ send_apdu(apdu);
+
+ return 2;
+}
+
+static int cmd_xmles(const char *arg)
+{
+ if (only_z3950())
+ return 1;
+ else
+ {
+ char *asn_buf = 0;
+ int noread = 0;
+ Odr_oid *oid;
+ char oid_str[51];
+ Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest);
+ Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
+
+
+ Z_External *ext = (Z_External *) odr_malloc(out, sizeof(*ext));
+
+ req->referenceId = set_refid (out);
+ req->taskSpecificParameters = ext;
+ ext->indirect_reference = 0;
+ ext->descriptor = 0;
+ ext->which = Z_External_octet;
+ ext->u.single_ASN1_type = (Odr_oct *) odr_malloc(out, sizeof(Odr_oct));
+ sscanf(arg, "%50s%n", oid_str, &noread);
+ if (noread == 0)
+ {
+ printf("Missing OID for xmles\n");
+ return 0;
+ }
+ arg += noread;
+ if (parse_cmd_doc(&arg, out, &asn_buf,
+ &ext->u.single_ASN1_type->len) == 0)
+ return 0;
+
+ ext->u.single_ASN1_type->buf = (unsigned char *) asn_buf;
+
+ oid = yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_EXTSERV, oid_str, out);
+ if (!oid)
+ {
+ printf("Bad OID: %s\n", oid_str);
+ return 0;
+ }
+
+ req->packageType = oid;
+
+ ext->direct_reference = oid;
+
+ send_apdu(apdu);
+
+ return 2;