+Z_APDU *create_admin_package(ZOOM_package p, int type,
+ Z_ESAdminOriginPartToKeep **toKeepP,
+ Z_ESAdminOriginPartNotToKeep **notToKeepP)
+{
+ Z_APDU *apdu = create_es_package(p, yaz_oid_extserv_admin);
+ 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,
+ p->odr_out);
+ if (num_db > 0)
+ first_db = db[0];
+
+ r->direct_reference = odr_oiddup(p->odr_out, yaz_oid_extserv_admin);
+ 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_xmlupdate_package(ZOOM_package p)
+{
+ Z_APDU *apdu = create_es_package(p, yaz_oid_extserv_xml_es);
+ Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
+ Z_External *ext = (Z_External *) odr_malloc(p->odr_out, sizeof(*ext));
+ int len;
+ const char *doc = ZOOM_options_getl(p->options, "doc", &len);
+
+ if (!doc)
+ {
+ doc = "";
+ len = 0;
+ }
+
+ req->taskSpecificParameters = ext;
+ ext->direct_reference = req->packageType;
+ ext->descriptor = 0;
+ ext->indirect_reference = 0;
+
+ ext->which = Z_External_octet;
+ ext->u.single_ASN1_type =
+ odr_create_Odr_oct(p->odr_out, (const unsigned char *) doc, len);
+ 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, p->odr_out);
+ const char *action = ZOOM_options_get(p->options, "action");
+ int recordIdOpaque_len;
+ const char *recordIdOpaque = ZOOM_options_getl(p->options, "recordIdOpaque",
+ &recordIdOpaque_len);
+ const char *recordIdNumber = ZOOM_options_get(p->options, "recordIdNumber");
+ int record_len;
+ const char *record_buf = ZOOM_options_getl(p->options, "record",
+ &record_len);
+ int recordOpaque_len;
+ const char *recordOpaque_buf = ZOOM_options_getl(p->options, "recordOpaque",
+ &recordOpaque_len);
+ 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;
+ 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 && !recordOpaque_buf)
+ {
+ record_buf = "void";
+ record_len = 4;
+ syntax_str = "SUTRS";
+ }
+
+ if (syntax_str)
+ {
+ syntax_oid = yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_RECSYN, syntax_str,
+ p->odr_out);
+ }
+ if (!syntax_oid)
+ return 0;
+
+ if (num_db > 0)
+ first_db = db[0];
+
+ 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 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, 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, package_oid);
+ 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 = odr_strdup_null(p->odr_out, elementSetName);
+
+ 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_create_Odr_oct(p->odr_out,
+ (const unsigned char *) recordIdOpaque,
+ recordIdOpaque_len);
+ }
+ 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;
+ if (correlationInfo_note || correlationInfo_id)
+ {
+ Z_IUCorrelationInfo *ci;
+ ci = notToKeep->elements[0]->correlationInfo =
+ (Z_IUCorrelationInfo *) odr_malloc(p->odr_out, sizeof(*ci));
+ ci->note = odr_strdup_null(p->odr_out, correlationInfo_note);
+ ci->id = correlationInfo_id ?
+ odr_intdup(p->odr_out, atoi(correlationInfo_id)) : 0;
+ }
+ else
+ notToKeep->elements[0]->correlationInfo = 0;
+ if (recordOpaque_buf)
+ {
+ notToKeep->elements[0]->record =
+ z_ext_record_oid_any(p->odr_out, syntax_oid,
+ recordOpaque_buf, recordOpaque_len);
+ }
+ else
+ {
+ notToKeep->elements[0]->record =
+ z_ext_record_oid(p->odr_out, syntax_oid,
+ record_buf, record_len);
+ }
+ }
+ if (0 && apdu)
+ {
+ ODR print = odr_createmem(ODR_PRINT);
+
+ z_APDU(print, &apdu, 0, 0);
+ odr_destroy(print);
+ }
+ return apdu;
+}
+