/* Called after each object ready to be stored */
p11_index_store_cb store;
+ /* Called after an object has been removed */
+ p11_index_remove_cb remove;
+
/* Called after objects change */
p11_index_notify_cb notify;
}
+static CK_RV
+default_remove (void *data,
+ p11_index *index,
+ CK_ATTRIBUTE *attrs)
+{
+ return CKR_OK;
+}
+
p11_index *
p11_index_new (p11_index_build_cb build,
p11_index_store_cb store,
+ p11_index_remove_cb remove,
p11_index_notify_cb notify,
void *data)
{
store = default_store;
if (notify == NULL)
notify = default_notify;
+ if (remove == NULL)
+ remove = default_remove;
index->build = build;
index->store = store;
index->notify = notify;
+ index->remove = remove;
index->data = data;
index->objects = p11_dict_new (p11_dict_ulongptr_hash,
CK_OBJECT_HANDLE handle)
{
index_object *obj;
+ CK_RV rv;
return_val_if_fail (index != NULL, CKR_GENERAL_ERROR);
if (!p11_dict_steal (index->objects, &handle, NULL, (void **)&obj))
return CKR_OBJECT_HANDLE_INVALID;
+ rv = (index->remove) (index->data, index, obj->attrs);
+
+ /* If the writer failed the remove, then add it back */
+ if (rv != CKR_OK) {
+ if (!p11_dict_set (index->objects, &obj->handle, obj))
+ return_val_if_reached (CKR_HOST_MEMORY);
+ return rv;
+ }
+
/* This takes ownership of the attributes */
index_notify (index, handle, obj->attrs);
obj->attrs = NULL;
static void
setup (void *unused)
{
- test.index = p11_index_new (NULL, NULL, NULL, NULL);
+ test.index = p11_index_new (NULL, NULL, NULL, NULL, NULL);
assert_ptr_not_null (test.index);
}
p11_index *index;
CK_RV rv;
- index = p11_index_new (on_index_build_fail, NULL, NULL, &match);
+ index = p11_index_new (on_index_build_fail, NULL, NULL, NULL, &match);
assert_ptr_not_null (index);
array = p11_array_new (p11_attrs_free);
p11_index *index;
CK_RV rv;
- index = p11_index_new (on_build_populate, NULL, NULL, "blah");
+ index = p11_index_new (on_build_populate, NULL, NULL, NULL, "blah");
assert_ptr_not_null (index);
rv = p11_index_add (index, original, 2, &handle);
p11_index *index;
CK_RV rv;
- index = p11_index_new (on_build_fail, NULL, NULL, "testo");
+ index = p11_index_new (on_build_fail, NULL, NULL, NULL, "testo");
assert_ptr_not_null (index);
rv = p11_index_add (index, okay, 2, &handle);
p11_index *index;
CK_RV rv;
- index = p11_index_new (NULL, NULL, on_change_check, "change-check");
+ index = p11_index_new (NULL, NULL, NULL, on_change_check, "change-check");
assert_ptr_not_null (index);
on_change_removing = false;
p11_index *index;
CK_RV rv;
- index = p11_index_new (NULL, NULL, on_change_check, "change-check");
+ index = p11_index_new (NULL, NULL, NULL, on_change_check, "change-check");
assert_ptr_not_null (index);
on_change_batching = true;
p11_index *index;
CK_RV rv;
- index = p11_index_new (NULL, NULL, on_change_nested, "change-nested");
+ index = p11_index_new (NULL, NULL, NULL, on_change_nested, "change-nested");
assert_ptr_not_null (index);
on_change_called = 0;
p11_index_free (index);
}
+static CK_RV
+on_remove_callback (void *data,
+ p11_index *index,
+ CK_ATTRIBUTE *attrs)
+{
+ int *removed = data;
+ assert_ptr_not_null (removed);
+ assert_num_eq (*removed, 0);
+ *removed = 1;
+ return CKR_OK;
+}
+
+static void
+test_remove_callback (void)
+{
+ CK_ATTRIBUTE original[] = {
+ { CKA_LABEL, "yay", 3 },
+ { CKA_VALUE, "eight", 5 },
+ { CKA_INVALID }
+
+ };
+
+ CK_OBJECT_HANDLE handle;
+ p11_index *index;
+ int removed = 0;
+ CK_RV rv;
+
+ index = p11_index_new (NULL, NULL, on_remove_callback, NULL, &removed);
+ assert_ptr_not_null (index);
+
+ rv = p11_index_add (index, original, 2, &handle);
+ assert_num_eq (rv, CKR_OK);
+
+ assert_ptr_not_null (p11_index_lookup (index, handle));
+
+ rv = p11_index_remove (index, handle);
+ assert_num_eq (rv, CKR_OK);
+
+ assert_num_eq (removed, 1);
+ assert_ptr_eq (p11_index_lookup (index, handle), NULL);
+
+ p11_index_free (index);
+}
+
+static CK_RV
+on_remove_fail (void *data,
+ p11_index *index,
+ CK_ATTRIBUTE *attrs)
+{
+ assert_str_eq (data, "remove-fail");
+ return CKR_DEVICE_REMOVED;
+}
+
+static void
+test_remove_fail (void)
+{
+ CK_ATTRIBUTE original[] = {
+ { CKA_LABEL, "yay", 3 },
+ { CKA_VALUE, "eight", 5 },
+ { CKA_INVALID }
+
+ };
+
+ CK_OBJECT_HANDLE handle;
+ p11_index *index;
+ CK_RV rv;
+
+ index = p11_index_new (NULL, NULL, on_remove_fail, NULL, "remove-fail");
+ assert_ptr_not_null (index);
+
+ rv = p11_index_add (index, original, 2, &handle);
+ assert (rv == CKR_OK);
+
+ assert_ptr_not_null (p11_index_lookup (index, handle));
+
+ rv = p11_index_remove (index, handle);
+ assert_num_eq (rv, CKR_DEVICE_REMOVED);
+
+ assert_ptr_not_null (p11_index_lookup (index, handle));
+
+ p11_index_free (index);
+}
+
int
main (int argc,
char *argv[])
p11_test (test_change_batch, "/index/change_batch");
p11_test (test_change_nested, "/index/change_nested");
p11_test (test_replace_all_build_fails, "/index/replace-all-build-fails");
+ p11_test (test_remove_callback, "/index/remove-callback");
+ p11_test (test_remove_fail, "/index/remove-fail");
return p11_test_run (argc, argv);
}