This change facilitates name translation for shared libraries. The
authorGeoff Thorpe <geoff@openssl.org>
Wed, 19 Apr 2000 21:45:17 +0000 (21:45 +0000)
committerGeoff Thorpe <geoff@openssl.org>
Wed, 19 Apr 2000 21:45:17 +0000 (21:45 +0000)
technique used is far from perfect and alternatives are welcome.
Basically if the translation flag is set, the string is not too
long, and there appears to be no path information in the string,
then it is converted to whatever the standard should be for the
DSO_METHOD in question, eg;
    blah --> libblah.so   on *nix, and
    blah --> blah.dll     on win32.

This change also introduces the DSO_ctrl() function that is used
by the name translation stuff.

CHANGES
crypto/dso/dso.h
crypto/dso/dso_dl.c
crypto/dso/dso_dlfcn.c
crypto/dso/dso_err.c
crypto/dso/dso_lib.c
crypto/dso/dso_null.c
crypto/dso/dso_win32.c

diff --git a/CHANGES b/CHANGES
index 4688929252e13e5797b223dc065a48e876e470a6..03b1f0059eabbfb445494578833700dca19255b4 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,13 @@
 
  Changes between 0.9.5a and 0.9.6  [xx XXX 2000]
 
 
  Changes between 0.9.5a and 0.9.6  [xx XXX 2000]
 
+  *) Added native name translation to the existing DSO code
+     that will convert (if the flag to do so is set) filenames
+     that are sufficiently small and have no path information
+     into a canonical native form. Eg. "blah" converted to
+     "libblah.so" or "blah.dll" etc.
+     [Geoff Thorpe]
+
   *) New function ERR_error_string_n(e, buf, len) which is like
      ERR_error_string(e, buf), but writes at most 'len' bytes
      including the 0 terminator.  For ERR_error_string_n, 'buf'
   *) New function ERR_error_string_n(e, buf, len) which is like
      ERR_error_string(e, buf), but writes at most 'len' bytes
      including the 0 terminator.  For ERR_error_string_n, 'buf'
index 91a44805e3557bd3e50bf6807c02cfecdc2604e8..281af47c2624db6112399f690af59227dd018177 100644 (file)
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
+/* These values are used as commands to DSO_ctrl() */
+#define DSO_CTRL_GET_FLAGS     1
+#define DSO_CTRL_SET_FLAGS     2
+#define DSO_CTRL_OR_FLAGS      3
+
+/* These flags control the translation of file-names from canonical to
+ * native. Eg. in the CryptoSwift support, the "dl" and "dlfcn"
+ * methods will translate "swift" -> "libswift.so" whereas the "win32"
+ * method will translate "swift" -> "swift.dll". NB: Until I can figure
+ * out how to be more "conventional" with this, the methods will only
+ * honour this flag if it looks like it was passed a file without any
+ * path and if the filename is small enough.
+ */
+#define DSO_FLAG_NAME_TRANSLATION 0x01
 
 typedef struct dso_st DSO;
 
 
 typedef struct dso_st DSO;
 
@@ -83,7 +97,11 @@ typedef struct dso_meth_st
        /* Unbinds a symbol */
        int (*dso_unbind)(DSO *dso, char *symname, void *symptr);
 #endif
        /* Unbinds a symbol */
        int (*dso_unbind)(DSO *dso, char *symname, void *symptr);
 #endif
+       /* The generic (yuck) "ctrl()" function. NB: Negative return
+        * values (rather than zero) indicate errors. */
+       long (*dso_ctrl)(DSO *dso, int cmd, long larg, void *parg);
 
 
+       /* [De]Initialisation handlers. */
        int (*init)(DSO *dso);
        int (*finish)(DSO *dso);
        } DSO_METHOD;
        int (*init)(DSO *dso);
        int (*finish)(DSO *dso);
        } DSO_METHOD;
@@ -113,6 +131,7 @@ DSO *       DSO_new_method(DSO_METHOD *method);
 int    DSO_free(DSO *dso);
 int    DSO_flags(DSO *dso);
 int    DSO_up(DSO *dso);
 int    DSO_free(DSO *dso);
 int    DSO_flags(DSO *dso);
 int    DSO_up(DSO *dso);
+long   DSO_ctrl(DSO *dso, int cmd, long larg, void *parg);
 
 void DSO_set_default_method(DSO_METHOD *meth);
 DSO_METHOD *DSO_get_default_method(void);
 
 void DSO_set_default_method(DSO_METHOD *meth);
 DSO_METHOD *DSO_get_default_method(void);
@@ -121,8 +140,11 @@ DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth);
 
 /* The all-singing all-dancing load function, you normally pass NULL
  * for the first and third parameters. Use DSO_up and DSO_free for
 
 /* The all-singing all-dancing load function, you normally pass NULL
  * for the first and third parameters. Use DSO_up and DSO_free for
- * reference count handling. */
-DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth);
+ * subsequent reference count handling. Any flags passed in will be set
+ * in the constructed DSO after its init() function but before the
+ * load operation. This will be done with;
+ *    DSO_ctrl(dso, DSO_CTRL_SET_FLAGS, flags, NULL); */
+DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags);
 
 /* This function binds to a function, variable, whatever inside a
  * shared library. */
 
 /* This function binds to a function, variable, whatever inside a
  * shared library. */
@@ -163,17 +185,21 @@ void ERR_load_DSO_strings(void);
 #define DSO_F_DLFCN_BIND                                100
 #define DSO_F_DLFCN_LOAD                                101
 #define DSO_F_DLFCN_UNLOAD                              102
 #define DSO_F_DLFCN_BIND                                100
 #define DSO_F_DLFCN_LOAD                                101
 #define DSO_F_DLFCN_UNLOAD                              102
-#define DSO_F_DL_BIND                                   103
-#define DSO_F_DL_LOAD                                   104
-#define DSO_F_DL_UNLOAD                                         105
-#define DSO_F_DSO_BIND                                  106
-#define DSO_F_DSO_FREE                                  107
-#define DSO_F_DSO_LOAD                                  108
-#define DSO_F_DSO_NEW_METHOD                            109
-#define DSO_F_DSO_UP                                    110
-#define DSO_F_WIN32_BIND                                111
-#define DSO_F_WIN32_LOAD                                112
-#define DSO_F_WIN32_UNLOAD                              113
+#define DSO_F_DLFCN_CTRL                                103
+#define DSO_F_DL_BIND                                   104
+#define DSO_F_DL_LOAD                                   105
+#define DSO_F_DL_UNLOAD                                         106
+#define DSO_F_DL_CTRL                                   107
+#define DSO_F_DSO_BIND                                  108
+#define DSO_F_DSO_FREE                                  109
+#define DSO_F_DSO_LOAD                                  110
+#define DSO_F_DSO_NEW_METHOD                            111
+#define DSO_F_DSO_UP                                    112
+#define DSO_F_DSO_CTRL                                  113
+#define DSO_F_WIN32_BIND                                114
+#define DSO_F_WIN32_LOAD                                115
+#define DSO_F_WIN32_UNLOAD                              116
+#define DSO_F_WIN32_CTRL                                117
 
 /* Reason codes. */
 #define DSO_R_FINISH_FAILED                             100
 
 /* Reason codes. */
 #define DSO_R_FINISH_FAILED                             100
@@ -183,6 +209,8 @@ void ERR_load_DSO_strings(void);
 #define DSO_R_SYM_FAILURE                               104
 #define DSO_R_UNLOAD_FAILED                             105
 #define DSO_R_UNSUPPORTED                               106
 #define DSO_R_SYM_FAILURE                               104
 #define DSO_R_UNLOAD_FAILED                             105
 #define DSO_R_UNSUPPORTED                               106
+#define DSO_R_UNKNOWN_COMMAND                           107
+#define DSO_R_CTRL_FAILED                               108
 
 #ifdef  __cplusplus
 }
 
 #ifdef  __cplusplus
 }
index e6e508d434239a4b596f9f489f0b15c08e2fefcd..a4152e7723259423e1b08eda1539d1957bc72b08 100644 (file)
@@ -69,6 +69,9 @@ DSO_METHOD *DSO_METHOD_dl(void)
 
 #include <dl.h>
 
 
 #include <dl.h>
 
+/* Part of the hack in "dl_load" ... */
+#define DSO_MAX_TRANSLATED_SIZE 256
+
 static int dl_load(DSO *dso, const char *filename);
 static int dl_unload(DSO *dso);
 static int dl_bind(DSO *dso, const char *symname, void **symptr);
 static int dl_load(DSO *dso, const char *filename);
 static int dl_unload(DSO *dso);
 static int dl_bind(DSO *dso, const char *symname, void **symptr);
@@ -77,6 +80,7 @@ static int dl_unbind(DSO *dso, char *symname, void *symptr);
 static int dl_init(DSO *dso);
 static int dl_finish(DSO *dso);
 #endif
 static int dl_init(DSO *dso);
 static int dl_finish(DSO *dso);
 #endif
+static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg);
 
 static DSO_METHOD dso_meth_dl = {
        "OpenSSL 'dl' shared library method",
 
 static DSO_METHOD dso_meth_dl = {
        "OpenSSL 'dl' shared library method",
@@ -87,6 +91,7 @@ static DSO_METHOD dso_meth_dl = {
 #if 0
        NULL, /* unbind */
 #endif
 #if 0
        NULL, /* unbind */
 #endif
+       dl_ctrl,
        NULL, /* init */
        NULL  /* finish */
        };
        NULL, /* init */
        NULL  /* finish */
        };
@@ -105,8 +110,20 @@ DSO_METHOD *DSO_METHOD_dl(void)
 static int dl_load(DSO *dso, const char *filename)
        {
        shl_t ptr;
 static int dl_load(DSO *dso, const char *filename)
        {
        shl_t ptr;
+       char translated[DSO_MAX_TRANSLATED_SIZE];
+       int len;
 
 
-       ptr = shl_load(filename, BIND_IMMEDIATE, NULL);
+       /* The same comment as in dlfcn_load applies here. bleurgh. */
+       len = strlen(filename);
+       if((dso->flags & DSO_FLAG_NAME_TRANSLATION) &&
+                       (len + 6 < DSO_MAX_TRANSLATED_SIZE) &&
+                       (strstr(filename, "/") == NULL))
+               {
+               sprintf(translated, "lib%s.so", filename);
+               ptr = shl_load(translated, BIND_IMMEDIATE, NULL);
+               }
+       else
+               ptr = shl_load(filename, BIND_IMMEDIATE, NULL);
        if(ptr == NULL)
                {
                DSOerr(DSO_F_DL_LOAD,DSO_R_LOAD_FAILED);
        if(ptr == NULL)
                {
                DSOerr(DSO_F_DL_LOAD,DSO_R_LOAD_FAILED);
@@ -163,7 +180,6 @@ static int dl_bind(DSO *dso, const char *symname, void **symptr)
                DSOerr(DSO_F_DL_BIND,DSO_R_STACK_ERROR);
                return(0);
                }
                DSOerr(DSO_F_DL_BIND,DSO_R_STACK_ERROR);
                return(0);
                }
-       /* Is this actually legal? */
        ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
        if(ptr == NULL)
                {
        ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
        if(ptr == NULL)
                {
@@ -179,4 +195,28 @@ static int dl_bind(DSO *dso, const char *symname, void **symptr)
        return(1);
        }
 
        return(1);
        }
 
+static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg)
+       {
+       if(dso == NULL)
+               {
+               DSOerr(DSO_F_DL_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+               return(-1);
+               }
+       switch(cmd)
+               {
+       case DSO_CTRL_GET_FLAGS:
+               return dso->flags;
+       case DSO_CTRL_SET_FLAGS:
+               dso->flags = (int)larg;
+               return(0);
+       case DSO_CTRL_OR_FLAGS:
+               dso->flags |= (int)larg;
+               return(0);
+       default:
+               break;
+               }
+       DSOerr(DSO_F_DL_CTRL,DSO_R_UNKNOWN_COMMAND);
+       return(-1);
+       }
+
 #endif /* DSO_DL */
 #endif /* DSO_DL */
index c5db28f3566c73077eda051d9102126be34a2670..cad1aedd4edd163e53f3c611c377ef29e9965729 100644 (file)
@@ -71,6 +71,9 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)
 #include <dlfcn.h>
 #endif
 
 #include <dlfcn.h>
 #endif
 
+/* Part of the hack in "dlfcn_load" ... */
+#define DSO_MAX_TRANSLATED_SIZE 256
+
 static int dlfcn_load(DSO *dso, const char *filename);
 static int dlfcn_unload(DSO *dso);
 static int dlfcn_bind(DSO *dso, const char *symname, void **symptr);
 static int dlfcn_load(DSO *dso, const char *filename);
 static int dlfcn_unload(DSO *dso);
 static int dlfcn_bind(DSO *dso, const char *symname, void **symptr);
@@ -79,6 +82,7 @@ static int dlfcn_unbind(DSO *dso, char *symname, void *symptr);
 static int dlfcn_init(DSO *dso);
 static int dlfcn_finish(DSO *dso);
 #endif
 static int dlfcn_init(DSO *dso);
 static int dlfcn_finish(DSO *dso);
 #endif
+static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg);
 
 static DSO_METHOD dso_meth_dlfcn = {
        "OpenSSL 'dlfcn' shared library method",
 
 static DSO_METHOD dso_meth_dlfcn = {
        "OpenSSL 'dlfcn' shared library method",
@@ -89,6 +93,7 @@ static DSO_METHOD dso_meth_dlfcn = {
 #if 0
        NULL, /* unbind */
 #endif
 #if 0
        NULL, /* unbind */
 #endif
+       dlfcn_ctrl,
        NULL, /* init */
        NULL  /* finish */
        };
        NULL, /* init */
        NULL  /* finish */
        };
@@ -105,8 +110,25 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)
 static int dlfcn_load(DSO *dso, const char *filename)
        {
        void *ptr;
 static int dlfcn_load(DSO *dso, const char *filename)
        {
        void *ptr;
+       char translated[DSO_MAX_TRANSLATED_SIZE];
+       int len;
 
 
-       ptr = dlopen(filename, RTLD_NOW);
+       /* NB: This is a hideous hack, but I'm not yet sure what
+        * to replace it with. This attempts to convert any filename,
+        * that looks like it has no path information, into a
+        * translated form, e. "blah" -> "libblah.so" */
+       len = strlen(filename);
+       if((dso->flags & DSO_FLAG_NAME_TRANSLATION) &&
+                       (len + 6 < DSO_MAX_TRANSLATED_SIZE) &&
+                       (strstr(filename, "/") == NULL))
+               {
+               sprintf(translated, "lib%s.so", filename);
+               ptr = dlopen(translated, RTLD_NOW);
+               }
+       else
+               {
+               ptr = dlopen(filename, RTLD_NOW);
+               }
        if(ptr == NULL)
                {
                DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED);
        if(ptr == NULL)
                {
                DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED);
@@ -178,4 +200,28 @@ static int dlfcn_bind(DSO *dso, const char *symname, void **symptr)
        return(1);
        }
 
        return(1);
        }
 
+static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg)
+       {
+       if(dso == NULL)
+               {
+               DSOerr(DSO_F_DLFCN_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+               return(-1);
+               }
+       switch(cmd)
+               {
+       case DSO_CTRL_GET_FLAGS:
+               return dso->flags;
+       case DSO_CTRL_SET_FLAGS:
+               dso->flags = (int)larg;
+               return(0);
+       case DSO_CTRL_OR_FLAGS:
+               dso->flags |= (int)larg;
+               return(0);
+       default:
+               break;
+               }
+       DSOerr(DSO_F_DLFCN_CTRL,DSO_R_UNKNOWN_COMMAND);
+       return(-1);
+       }
+
 #endif /* DSO_DLFCN */
 #endif /* DSO_DLFCN */
index efe32260417fdfa1c1da852e0f54c628ad4ccf1e..5d2457a9fffc04e799f4ec7626f952907c367630 100644 (file)
 #ifndef NO_ERR
 static ERR_STRING_DATA DSO_str_functs[]=
        {
 #ifndef NO_ERR
 static ERR_STRING_DATA DSO_str_functs[]=
        {
-{ERR_PACK(0,DSO_F_DLFCN_BIND,0),       "DLFCN_BIND"},
-{ERR_PACK(0,DSO_F_DLFCN_LOAD,0),       "DLFCN_LOAD"},
-{ERR_PACK(0,DSO_F_DLFCN_UNLOAD,0),     "DLFCN_UNLOAD"},
-{ERR_PACK(0,DSO_F_DL_BIND,0),  "DL_BIND"},
-{ERR_PACK(0,DSO_F_DL_LOAD,0),  "DL_LOAD"},
-{ERR_PACK(0,DSO_F_DL_UNLOAD,0),        "DL_UNLOAD"},
+{ERR_PACK(0,DSO_F_DLFCN_BIND,0),       "dlfcn_bind"},
+{ERR_PACK(0,DSO_F_DLFCN_LOAD,0),       "dlfcn_load"},
+{ERR_PACK(0,DSO_F_DLFCN_UNLOAD,0),     "dlfcn_unload"},
+{ERR_PACK(0,DSO_F_DLFCN_CTRL,0),       "dlfcn_ctrl"},
+{ERR_PACK(0,DSO_F_DL_BIND,0),  "dl_bind"},
+{ERR_PACK(0,DSO_F_DL_LOAD,0),  "dl_load"},
+{ERR_PACK(0,DSO_F_DL_UNLOAD,0),        "dl_unload"},
+{ERR_PACK(0,DSO_F_DL_CTRL,0),  "dl_ctrl"},
 {ERR_PACK(0,DSO_F_DSO_BIND,0), "DSO_bind"},
 {ERR_PACK(0,DSO_F_DSO_FREE,0), "DSO_free"},
 {ERR_PACK(0,DSO_F_DSO_LOAD,0), "DSO_load"},
 {ERR_PACK(0,DSO_F_DSO_NEW_METHOD,0),   "DSO_new_method"},
 {ERR_PACK(0,DSO_F_DSO_UP,0),   "DSO_up"},
 {ERR_PACK(0,DSO_F_DSO_BIND,0), "DSO_bind"},
 {ERR_PACK(0,DSO_F_DSO_FREE,0), "DSO_free"},
 {ERR_PACK(0,DSO_F_DSO_LOAD,0), "DSO_load"},
 {ERR_PACK(0,DSO_F_DSO_NEW_METHOD,0),   "DSO_new_method"},
 {ERR_PACK(0,DSO_F_DSO_UP,0),   "DSO_up"},
-{ERR_PACK(0,DSO_F_WIN32_BIND,0),       "WIN32_BIND"},
-{ERR_PACK(0,DSO_F_WIN32_LOAD,0),       "WIN32_LOAD"},
-{ERR_PACK(0,DSO_F_WIN32_UNLOAD,0),     "WIN32_UNLOAD"},
+{ERR_PACK(0,DSO_F_DSO_CTRL,0), "DSO_ctrl"},
+{ERR_PACK(0,DSO_F_WIN32_BIND,0),       "win32_bind"},
+{ERR_PACK(0,DSO_F_WIN32_LOAD,0),       "win32_load"},
+{ERR_PACK(0,DSO_F_WIN32_UNLOAD,0),     "win32_unload"},
+{ERR_PACK(0,DSO_F_WIN32_CTRL,0),       "win32_ctrl"},
 {0,NULL}
        };
 
 {0,NULL}
        };
 
@@ -92,6 +96,8 @@ static ERR_STRING_DATA DSO_str_reasons[]=
 {DSO_R_SYM_FAILURE                       ,"could not bind to the requested symbol name"},
 {DSO_R_UNLOAD_FAILED                     ,"could not unload the shared library"},
 {DSO_R_UNSUPPORTED                       ,"functionality not supported"},
 {DSO_R_SYM_FAILURE                       ,"could not bind to the requested symbol name"},
 {DSO_R_UNLOAD_FAILED                     ,"could not unload the shared library"},
 {DSO_R_UNSUPPORTED                       ,"functionality not supported"},
+{DSO_R_UNKNOWN_COMMAND                  ,"unknown control command"},
+{DSO_R_CTRL_FAILED                      ,"control command failed"},
 {0,NULL}
        };
 
 {0,NULL}
        };
 
index 9430d0d76f6edc03c831b3e197a4e9dbe53b65ee..f41ebf1aa47924f0b336f2248d3f3c88a1d7a182 100644 (file)
@@ -187,7 +187,7 @@ int DSO_up(DSO *dso)
        return(1);
        }
 
        return(1);
        }
 
-DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth)
+DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags)
        {
        DSO *ret;
        int allocated = 0;
        {
        DSO *ret;
        int allocated = 0;
@@ -209,6 +209,15 @@ DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth)
                }
        else
                ret = dso;
                }
        else
                ret = dso;
+       /* Bleurgh ... have to check for negative return values for
+        * errors. <grimace> */
+       if(DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0)
+               {
+               DSOerr(DSO_F_DSO_LOAD,DSO_R_CTRL_FAILED);
+               if(allocated)
+                       DSO_free(ret);
+               return(NULL);
+               }
        if(ret->meth->dso_load == NULL)
                {
                DSOerr(DSO_F_DSO_LOAD,DSO_R_UNSUPPORTED);
        if(ret->meth->dso_load == NULL)
                {
                DSOerr(DSO_F_DSO_LOAD,DSO_R_UNSUPPORTED);
@@ -249,3 +258,26 @@ void *DSO_bind(DSO *dso, const char *symname)
        /* Success */
        return(ret);
        }
        /* Success */
        return(ret);
        }
+
+/* I don't really like these *_ctrl functions very much to be perfectly
+ * honest. For one thing, I think I have to return a negative value for
+ * any error because possible DSO_ctrl() commands may return values
+ * such as "size"s that can legitimately be zero (making the standard
+ * "if(DSO_cmd(...))" form that works almost everywhere else fail at
+ * odd times. I'd prefer "output" values to be passed by reference and
+ * the return value as success/failure like usual ... but we conform
+ * when we must... :-) */
+long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg)
+       {
+       if(dso == NULL)
+               {
+               DSOerr(DSO_F_DSO_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+               return(-1);
+               }
+       if((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL))
+               {
+               DSOerr(DSO_F_DSO_CTRL,DSO_R_UNSUPPORTED);
+               return(-1);
+               }
+       return(dso->meth->dso_ctrl(dso,cmd,larg,parg));
+       }
index ee6a31e32d825f5e772bd8aeed0917d6b8bc0af8..79e6eddca29e00ed075f3eaae3c8144d83acc11a 100644 (file)
@@ -72,6 +72,7 @@ static DSO_METHOD dso_meth_null = {
 #if 0
        NULL, /* unbind */
 #endif
 #if 0
        NULL, /* unbind */
 #endif
+       NULL, /* ctrl */
        NULL, /* init */
        NULL  /* finish */
        };
        NULL, /* init */
        NULL  /* finish */
        };
index 296e10ff6ffd7c64870e2095b7f783307a56a714..edf5d75b0f6a7e78c9087ae457ededc9d605a03a 100644 (file)
@@ -67,6 +67,9 @@ DSO_METHOD *DSO_METHOD_win32(void)
        }
 #else
 
        }
 #else
 
+/* Part of the hack in "win32_load" ... */
+#define DSO_MAX_TRANSLATED_SIZE 256
+
 static int win32_load(DSO *dso, const char *filename);
 static int win32_unload(DSO *dso);
 static int win32_bind(DSO *dso, const char *symname, void **symptr);
 static int win32_load(DSO *dso, const char *filename);
 static int win32_unload(DSO *dso);
 static int win32_bind(DSO *dso, const char *symname, void **symptr);
@@ -75,6 +78,7 @@ static int win32_unbind(DSO *dso, char *symname, void *symptr);
 static int win32_init(DSO *dso);
 static int win32_finish(DSO *dso);
 #endif
 static int win32_init(DSO *dso);
 static int win32_finish(DSO *dso);
 #endif
+static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg);
 
 static DSO_METHOD dso_meth_win32 = {
        "OpenSSL 'win32' shared library method",
 
 static DSO_METHOD dso_meth_win32 = {
        "OpenSSL 'win32' shared library method",
@@ -85,6 +89,7 @@ static DSO_METHOD dso_meth_win32 = {
 #if 0
        NULL, /* unbind */
 #endif
 #if 0
        NULL, /* unbind */
 #endif
+       win32_ctrl,
        NULL, /* init */
        NULL  /* finish */
        };
        NULL, /* init */
        NULL  /* finish */
        };
@@ -96,14 +101,32 @@ DSO_METHOD *DSO_METHOD_win32(void)
 
 /* For this DSO_METHOD, our meth_data STACK will contain;
  * (i) a pointer to the handle (HINSTANCE) returned from
 
 /* For this DSO_METHOD, our meth_data STACK will contain;
  * (i) a pointer to the handle (HINSTANCE) returned from
- *      LoadLibrary(), and copied.
+ *     LoadLibrary(), and copied.
  */
 
 static int win32_load(DSO *dso, const char *filename)
        {
        HINSTANCE h, *p;
  */
 
 static int win32_load(DSO *dso, const char *filename)
        {
        HINSTANCE h, *p;
+       char translated[DSO_MAX_TRANSLATED_SIZE];
+       int len;
 
 
-       h = LoadLibrary(filename);
+       /* NB: This is a hideous hack, but I'm not yet sure what
+        * to replace it with. This attempts to convert any filename,
+        * that looks like it has no path information, into a
+        * translated form, e. "blah" -> "blah.dll" ... I'm more
+        * comfortable putting hacks into win32 code though ;-) */
+       len = strlen(filename);
+       if((dso->flags & DSO_FLAG_NAME_TRANSLATION) &&
+                       (len + 4 < DSO_MAX_TRANSLATED_SIZE) &&
+                       (strstr(filename, "/") == NULL)
+                       (strstr(filename, "\\") == NULL)
+                       (strstr(filename, ":") == NULL))
+               {
+               sprintf(translated, "%s.dll", filename);
+               h = LoadLibrary(translated);
+               }
+       else
+               h = LoadLibrary(filename);
        if(h == NULL)
                {
                DSOerr(DSO_F_WIN32_LOAD,DSO_R_LOAD_FAILED);
        if(h == NULL)
                {
                DSOerr(DSO_F_WIN32_LOAD,DSO_R_LOAD_FAILED);
@@ -190,4 +213,28 @@ static int win32_bind(DSO *dso, const char *symname, void **symptr)
        return(1);
        }
 
        return(1);
        }
 
+static int win32_ctrl(DSO *dso, int cmd, long larg, void *parg)
+        {
+        if(dso == NULL)
+                {
+                DSOerr(DSO_F_WIN32_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+                return(-1);
+                }
+        switch(cmd)
+                {
+        case DSO_CTRL_GET_FLAGS:
+                return dso->flags;
+        case DSO_CTRL_SET_FLAGS:
+                dso->flags = (int)larg;
+                return(0);
+        case DSO_CTRL_OR_FLAGS:
+                dso->flags |= (int)larg;
+                return(0);
+        default:
+                break;
+                }
+        DSOerr(DSO_F_WIN32_CTRL,DSO_R_UNKNOWN_COMMAND);
+        return(-1);
+        }
+
 #endif /* WIN32 */
 #endif /* WIN32 */