aboutsummaryrefslogtreecommitdiffstats
path: root/cipher/dynload.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cipher/dynload.c93
1 files changed, 91 insertions, 2 deletions
diff --git a/cipher/dynload.c b/cipher/dynload.c
index ff40dafff..7278928f1 100644
--- a/cipher/dynload.c
+++ b/cipher/dynload.c
@@ -39,6 +39,7 @@
typedef struct ext_list {
struct ext_list *next;
+ int internal;
#ifdef HAVE_DL_DLOPEN
void *handle; /* handle from dlopen() */
#else
@@ -83,7 +84,7 @@ static int dld_available;
void
register_cipher_extension( const char *mainpgm, const char *fname )
{
- EXTLIST r, el;
+ EXTLIST r, el, intex;
char *p, *pe;
#ifdef HAVE_DLD_DLD_LINK
@@ -114,13 +115,53 @@ register_cipher_extension( const char *mainpgm, const char *fname )
el->hintstr = NULL;
/* check that it is not already registered */
- for(r = extensions; r; r = r->next )
+ intex = NULL;
+ for(r = extensions; r; r = r->next ) {
+ if( !compare_filenames(r->name, el->name) ) {
+ log_info("extension '%s' already registered\n", el->name );
+ m_free(el);
+ return;
+ }
+ else if( r->internal )
+ intex = r;
+ }
+ /* and register */
+ /* we put them after the internal extension modules */
+ /* this is so that the external modules do not get loaded */
+ /* as soon as the internal modules are requested */
+ if( intex ) {
+ el->next = intex->next;
+ intex->next = el;
+ }
+ else {
+ el->next = extensions;
+ extensions = el;
+ }
+}
+
+void
+register_internal_cipher_extension(
+ const char *module_id,
+ void * (*enumfunc)(int, int*, int*, int*)
+ )
+{
+ EXTLIST r, el;
+
+ el = m_alloc_clear( sizeof *el + strlen(module_id) );
+ strcpy(el->name, module_id );
+ el->internal = 1;
+
+ /* check that it is not already registered */
+ for(r = extensions; r; r = r->next ) {
if( !compare_filenames(r->name, el->name) ) {
log_info("extension '%s' already registered\n", el->name );
m_free(el);
return;
}
+ }
/* and register */
+ el->enumfunc = enumfunc;
+ el->handle = (void*)1;
el->next = extensions;
extensions = el;
}
@@ -455,3 +496,51 @@ enum_gnupgext_pubkeys( void **enum_context, int *algo,
return NULL;
}
+
+int (*
+dynload_getfnc_gather_random())(byte*, size_t*, int)
+{
+ EXTLIST r;
+ void *sym;
+
+ for( r = extensions; r; r = r->next ) {
+ int seq, class, vers;
+
+ if( r->failed )
+ continue;
+ if( !r->handle && load_extension(r) )
+ continue;
+ seq = 0;
+ while( (sym = (*r->enumfunc)(40, &seq, &class, &vers)) ) {
+ if( vers != 1 || class != 40 )
+ continue;
+ return (int (*)(byte*, size_t*, int))sym;
+ }
+ }
+ return NULL;
+}
+
+
+void (*
+dynload_getfnc_fast_random_poll())( void (*)(const void*, size_t, int))
+{
+ EXTLIST r;
+ void *sym;
+
+ for( r = extensions; r; r = r->next ) {
+ int seq, class, vers;
+
+ if( r->failed )
+ continue;
+ if( !r->handle && load_extension(r) )
+ continue;
+ seq = 0;
+ while( (sym = (*r->enumfunc)(41, &seq, &class, &vers)) ) {
+ if( vers != 1 || class != 41 )
+ continue;
+ return (void (*)( void (*)(const void*, size_t, int)))sym;
+ }
+ }
+ return NULL;
+}
+