+DEFINE_STACK_OF(OSSL_STORE_LOADER)
+static int store_cmp(const OSSL_STORE_LOADER * const *a,
+ const OSSL_STORE_LOADER * const *b)
+{
+ return strcmp(OSSL_PROVIDER_get0_name(OSSL_STORE_LOADER_get0_provider(*a)),
+ OSSL_PROVIDER_get0_name(OSSL_STORE_LOADER_get0_provider(*b)));
+}
+
+static void collect_store_loaders(OSSL_STORE_LOADER *store, void *stack)
+{
+ STACK_OF(OSSL_STORE_LOADER) *store_stack = stack;
+
+ if (sk_OSSL_STORE_LOADER_push(store_stack, store) > 0)
+ OSSL_STORE_LOADER_up_ref(store);
+}
+
+static void list_store_loaders(void)
+{
+ STACK_OF(OSSL_STORE_LOADER) *stores = sk_OSSL_STORE_LOADER_new(store_cmp);
+ int i;
+
+ if (stores == NULL) {
+ BIO_printf(bio_err, "ERROR: Memory allocation\n");
+ return;
+ }
+ BIO_printf(bio_out, "Provided STORE LOADERs:\n");
+ OSSL_STORE_LOADER_do_all_provided(app_get0_libctx(), collect_store_loaders,
+ stores);
+ sk_OSSL_STORE_LOADER_sort(stores);
+ for (i = 0; i < sk_OSSL_STORE_LOADER_num(stores); i++) {
+ const OSSL_STORE_LOADER *m = sk_OSSL_STORE_LOADER_value(stores, i);
+ STACK_OF(OPENSSL_CSTRING) *names = NULL;
+
+ if (select_name != NULL && !OSSL_STORE_LOADER_is_a(m, select_name))
+ continue;
+
+ names = sk_OPENSSL_CSTRING_new(name_cmp);
+ if (names != NULL && OSSL_STORE_LOADER_names_do_all(m, collect_names,
+ names)) {
+ BIO_printf(bio_out, " ");
+ print_names(bio_out, names);
+
+ BIO_printf(bio_out, " @ %s\n",
+ OSSL_PROVIDER_get0_name(OSSL_STORE_LOADER_get0_provider(m)));
+ }
+ sk_OPENSSL_CSTRING_free(names);
+ }
+ sk_OSSL_STORE_LOADER_pop_free(stores, OSSL_STORE_LOADER_free);
+}
+