Blame SOURCES/0009-Simplify-plugin-loading-code.patch

d1ad9f
From 593109802b52e3f89c3a65436bfdba78f8c517c4 Mon Sep 17 00:00:00 2001
d1ad9f
From: Greg Hudson <ghudson@mit.edu>
d1ad9f
Date: Thu, 23 Jun 2022 16:41:40 -0400
d1ad9f
Subject: [PATCH] Simplify plugin loading code
d1ad9f
d1ad9f
Remove the USE_CFBUNDLE code, which was only used by KfM.  Handle
d1ad9f
platform conditionals according to current practice.  Use
d1ad9f
k5_dir_filenames() instead of opendir() and remove the Windows
d1ad9f
implementation of opendir().
d1ad9f
---
d1ad9f
 src/util/support/plugins.c | 507 +++++++++++--------------------------
d1ad9f
 1 file changed, 150 insertions(+), 357 deletions(-)
d1ad9f
d1ad9f
diff --git a/src/util/support/plugins.c b/src/util/support/plugins.c
d1ad9f
index c6a9a21d57..0850565687 100644
d1ad9f
--- a/src/util/support/plugins.c
d1ad9f
+++ b/src/util/support/plugins.c
d1ad9f
@@ -29,16 +29,6 @@
d1ad9f
 #if USE_DLOPEN
d1ad9f
 #include <dlfcn.h>
d1ad9f
 #endif
d1ad9f
-#include <sys/types.h>
d1ad9f
-#ifdef HAVE_SYS_STAT_H
d1ad9f
-#include <sys/stat.h>
d1ad9f
-#endif
d1ad9f
-#ifdef HAVE_SYS_PARAM_H
d1ad9f
-#include <sys/param.h>
d1ad9f
-#endif
d1ad9f
-#ifdef HAVE_UNISTD_H
d1ad9f
-#include <unistd.h>
d1ad9f
-#endif
d1ad9f
 
d1ad9f
 #if USE_DLOPEN
d1ad9f
 #ifdef RTLD_GROUP
d1ad9f
@@ -68,16 +58,6 @@
d1ad9f
 #endif
d1ad9f
 #endif
d1ad9f
 
d1ad9f
-#if USE_DLOPEN && USE_CFBUNDLE
d1ad9f
-#include <CoreFoundation/CoreFoundation.h>
d1ad9f
-
d1ad9f
-/* Currently CoreFoundation only exists on the Mac so we just use
d1ad9f
- * pthreads directly to avoid creating empty function calls on other
d1ad9f
- * platforms.  If a thread initializer ever gets created in the common
d1ad9f
- * plugin code, move this there */
d1ad9f
-static pthread_mutex_t krb5int_bundle_mutex = PTHREAD_MUTEX_INITIALIZER;
d1ad9f
-#endif
d1ad9f
-
d1ad9f
 #include <stdarg.h>
d1ad9f
 static void Tprintf (const char *fmt, ...)
d1ad9f
 {
d1ad9f
@@ -90,374 +70,193 @@ static void Tprintf (const char *fmt, ...)
d1ad9f
 }
d1ad9f
 
d1ad9f
 struct plugin_file_handle {
d1ad9f
-#if USE_DLOPEN
d1ad9f
+#if defined(USE_DLOPEN)
d1ad9f
     void *dlhandle;
d1ad9f
-#endif
d1ad9f
-#ifdef _WIN32
d1ad9f
-    HMODULE hinstPlugin;
d1ad9f
-#endif
d1ad9f
-#if !defined (USE_DLOPEN) && !defined (_WIN32)
d1ad9f
+#elif defined(_WIN32)
d1ad9f
+    HMODULE module;
d1ad9f
+#else
d1ad9f
     char dummy;
d1ad9f
 #endif
d1ad9f
 };
d1ad9f
 
d1ad9f
-#ifdef _WIN32
d1ad9f
-struct dirent {
d1ad9f
-    long d_ino;                 /* inode (always 1 in WIN32) */
d1ad9f
-    off_t d_off;                /* offset to this dirent */
d1ad9f
-    unsigned short d_reclen;    /* length of d_name */
d1ad9f
-    char d_name[_MAX_FNAME+1];  /* filename (null terminated) */
d1ad9f
-};
d1ad9f
-
d1ad9f
-typedef struct {
d1ad9f
-    intptr_t handle;            /* _findfirst/_findnext handle */
d1ad9f
-    short offset;               /* offset into directory */
d1ad9f
-    short finished;             /* 1 if there are not more files */
d1ad9f
-    struct _finddata_t fileinfo;/* from _findfirst/_findnext */
d1ad9f
-    char *dir;                  /* the dir we are reading */
d1ad9f
-    struct dirent dent;         /* the dirent to return */
d1ad9f
-} DIR;
d1ad9f
+#if defined(USE_DLOPEN)
d1ad9f
 
d1ad9f
-DIR * opendir(const char *dir)
d1ad9f
+static long
d1ad9f
+open_plugin_dlfcn(struct plugin_file_handle *h, const char *filename,
d1ad9f
+                  struct errinfo *ep)
d1ad9f
 {
d1ad9f
-    DIR *dp;
d1ad9f
-    char *filespec;
d1ad9f
-    intptr_t handle;
d1ad9f
-    int index;
d1ad9f
-
d1ad9f
-    filespec = malloc(strlen(dir) + 2 + 1);
d1ad9f
-    strcpy(filespec, dir);
d1ad9f
-    index = strlen(filespec) - 1;
d1ad9f
-    if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
d1ad9f
-        filespec[index] = '\0';
d1ad9f
-    strcat(filespec, "/*");
d1ad9f
-
d1ad9f
-    dp = (DIR *)malloc(sizeof(DIR));
d1ad9f
-    dp->offset = 0;
d1ad9f
-    dp->finished = 0;
d1ad9f
-    dp->dir = strdup(dir);
d1ad9f
-
d1ad9f
-    if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) {
d1ad9f
-        if (errno == ENOENT)
d1ad9f
-            dp->finished = 1;
d1ad9f
-        else {
d1ad9f
-            free(filespec);
d1ad9f
-            free(dp->dir);
d1ad9f
-            free(dp);
d1ad9f
-            return NULL;
d1ad9f
-        }
d1ad9f
+    const char *e;
d1ad9f
+
d1ad9f
+    h->dlhandle = dlopen(filename, PLUGIN_DLOPEN_FLAGS);
d1ad9f
+    if (h->dlhandle == NULL) {
d1ad9f
+        e = dlerror();
d1ad9f
+        if (e == NULL)
d1ad9f
+            e = _("unknown failure");
d1ad9f
+        Tprintf("dlopen(%s): %s\n", filename, e);
d1ad9f
+        k5_set_error(ep, ENOENT, _("unable to load plugin [%s]: %s"),
d1ad9f
+                     filename, e);
d1ad9f
+        return ENOENT;
d1ad9f
     }
d1ad9f
-
d1ad9f
-    dp->handle = handle;
d1ad9f
-    free(filespec);
d1ad9f
-
d1ad9f
-    return dp;
d1ad9f
+    return 0;
d1ad9f
 }
d1ad9f
+#define open_plugin open_plugin_dlfcn
d1ad9f
 
d1ad9f
-struct dirent * readdir(DIR *dp)
d1ad9f
+static long
d1ad9f
+get_sym_dlfcn(struct plugin_file_handle *h, const char *csymname,
d1ad9f
+              void **sym_out, struct errinfo *ep)
d1ad9f
 {
d1ad9f
-    if (!dp || dp->finished) return NULL;
d1ad9f
-
d1ad9f
-    if (dp->offset != 0) {
d1ad9f
-        if (_findnext(dp->handle, &(dp->fileinfo)) < 0) {
d1ad9f
-            dp->finished = 1;
d1ad9f
-            return NULL;
d1ad9f
-        }
d1ad9f
+    const char *e;
d1ad9f
+
d1ad9f
+    if (h->dlhandle == NULL)
d1ad9f
+        return ENOENT;
d1ad9f
+    *sym_out = dlsym(h->dlhandle, csymname);
d1ad9f
+    if (*sym_out == NULL) {
d1ad9f
+        e = dlerror();
d1ad9f
+        if (e == NULL)
d1ad9f
+            e = _("unknown failure");
d1ad9f
+        Tprintf("dlsym(%s): %s\n", csymname, e);
d1ad9f
+        k5_set_error(ep, ENOENT, "%s", e);
d1ad9f
+        return ENOENT;
d1ad9f
     }
d1ad9f
-    dp->offset++;
d1ad9f
-
d1ad9f
-    strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME);
d1ad9f
-    dp->dent.d_ino = 1;
d1ad9f
-    dp->dent.d_reclen = (unsigned short)strlen(dp->dent.d_name);
d1ad9f
-    dp->dent.d_off = dp->offset;
d1ad9f
-
d1ad9f
-    return &(dp->dent);
d1ad9f
-}
d1ad9f
-
d1ad9f
-int closedir(DIR *dp)
d1ad9f
-{
d1ad9f
-    if (!dp) return 0;
d1ad9f
-    _findclose(dp->handle);
d1ad9f
-    free(dp->dir);
d1ad9f
-    free(dp);
d1ad9f
-
d1ad9f
     return 0;
d1ad9f
 }
d1ad9f
-#endif
d1ad9f
+#define get_sym get_sym_dlfcn
d1ad9f
 
d1ad9f
-long KRB5_CALLCONV
d1ad9f
-krb5int_open_plugin (const char *filepath, struct plugin_file_handle **h, struct errinfo *ep)
d1ad9f
+static void
d1ad9f
+close_plugin_dlfcn(struct plugin_file_handle *h)
d1ad9f
 {
d1ad9f
-    long err = 0;
d1ad9f
-    struct plugin_file_handle *htmp = NULL;
d1ad9f
-    int got_plugin = 0;
d1ad9f
-#if defined(USE_CFBUNDLE) || defined(_WIN32)
d1ad9f
-    struct stat statbuf;
d1ad9f
-
d1ad9f
-    if (!err) {
d1ad9f
-        if (stat (filepath, &statbuf) < 0) {
d1ad9f
-            err = errno;
d1ad9f
-            Tprintf ("stat(%s): %s\n", filepath, strerror (err));
d1ad9f
-            k5_set_error(ep, err, _("unable to find plugin [%s]: %s"),
d1ad9f
-                         filepath, strerror(err));
d1ad9f
-        }
d1ad9f
-    }
d1ad9f
-#endif
d1ad9f
-
d1ad9f
-    if (!err) {
d1ad9f
-        htmp = calloc (1, sizeof (*htmp)); /* calloc initializes ptrs to NULL */
d1ad9f
-        if (htmp == NULL) { err = ENOMEM; }
d1ad9f
-    }
d1ad9f
-
d1ad9f
-#if USE_DLOPEN
d1ad9f
-    if (!err
d1ad9f
-#if USE_CFBUNDLE
d1ad9f
-                 && ((statbuf.st_mode & S_IFMT) == S_IFREG
d1ad9f
-                 || (statbuf.st_mode & S_IFMT) == S_IFDIR)
d1ad9f
-#endif /* USE_CFBUNDLE */
d1ad9f
-        ) {
d1ad9f
-        void *handle = NULL;
d1ad9f
-
d1ad9f
-#if USE_CFBUNDLE
d1ad9f
-        char executablepath[MAXPATHLEN];
d1ad9f
-
d1ad9f
-        if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
d1ad9f
-            int lock_err = 0;
d1ad9f
-            CFStringRef pluginString = NULL;
d1ad9f
-            CFURLRef pluginURL = NULL;
d1ad9f
-            CFBundleRef pluginBundle = NULL;
d1ad9f
-            CFURLRef executableURL = NULL;
d1ad9f
-
d1ad9f
-            /* Lock around CoreFoundation calls since objects are refcounted
d1ad9f
-             * and the refcounts are not thread-safe.  Using pthreads directly
d1ad9f
-             * because this code is Mac-specific */
d1ad9f
-            lock_err = pthread_mutex_lock(&krb5int_bundle_mutex);
d1ad9f
-            if (lock_err) { err = lock_err; }
d1ad9f
-
d1ad9f
-            if (!err) {
d1ad9f
-                pluginString = CFStringCreateWithCString (kCFAllocatorDefault,
d1ad9f
-                                                          filepath,
d1ad9f
-                                                          kCFStringEncodingASCII);
d1ad9f
-                if (pluginString == NULL) { err = ENOMEM; }
d1ad9f
-            }
d1ad9f
-
d1ad9f
-            if (!err) {
d1ad9f
-                pluginURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault,
d1ad9f
-                                                           pluginString,
d1ad9f
-                                                           kCFURLPOSIXPathStyle,
d1ad9f
-                                                           true);
d1ad9f
-                if (pluginURL == NULL) { err = ENOMEM; }
d1ad9f
-            }
d1ad9f
-
d1ad9f
-            if (!err) {
d1ad9f
-                pluginBundle = CFBundleCreate (kCFAllocatorDefault, pluginURL);
d1ad9f
-                if (pluginBundle == NULL) { err = ENOENT; } /* XXX need better error */
d1ad9f
-            }
d1ad9f
-
d1ad9f
-            if (!err) {
d1ad9f
-                executableURL = CFBundleCopyExecutableURL (pluginBundle);
d1ad9f
-                if (executableURL == NULL) { err = ENOMEM; }
d1ad9f
-            }
d1ad9f
-
d1ad9f
-            if (!err) {
d1ad9f
-                if (!CFURLGetFileSystemRepresentation (executableURL,
d1ad9f
-                                                       true, /* absolute */
d1ad9f
-                                                       (UInt8 *)executablepath,
d1ad9f
-                                                       sizeof (executablepath))) {
d1ad9f
-                    err = ENOMEM;
d1ad9f
-                }
d1ad9f
-            }
d1ad9f
-
d1ad9f
-            if (!err) {
d1ad9f
-                /* override the path the caller passed in */
d1ad9f
-                filepath = executablepath;
d1ad9f
-            }
d1ad9f
-
d1ad9f
-            if (executableURL    != NULL) { CFRelease (executableURL); }
d1ad9f
-            if (pluginBundle     != NULL) { CFRelease (pluginBundle); }
d1ad9f
-            if (pluginURL        != NULL) { CFRelease (pluginURL); }
d1ad9f
-            if (pluginString     != NULL) { CFRelease (pluginString); }
d1ad9f
-
d1ad9f
-            /* unlock after CFRelease calls since they modify refcounts */
d1ad9f
-            if (!lock_err) { pthread_mutex_unlock (&krb5int_bundle_mutex); }
d1ad9f
-        }
d1ad9f
-#endif /* USE_CFBUNDLE */
d1ad9f
-
d1ad9f
-        if (!err) {
d1ad9f
-            handle = dlopen(filepath, PLUGIN_DLOPEN_FLAGS);
d1ad9f
-            if (handle == NULL) {
d1ad9f
-                const char *e = dlerror();
d1ad9f
-                if (e == NULL)
d1ad9f
-                    e = _("unknown failure");
d1ad9f
-                Tprintf ("dlopen(%s): %s\n", filepath, e);
d1ad9f
-                err = ENOENT; /* XXX */
d1ad9f
-                k5_set_error(ep, err, _("unable to load plugin [%s]: %s"),
d1ad9f
-                             filepath, e);
d1ad9f
-            }
d1ad9f
-        }
d1ad9f
+    if (h->dlhandle != NULL)
d1ad9f
+        dlclose(h->dlhandle);
d1ad9f
+}
d1ad9f
+#define close_plugin close_plugin_dlfcn
d1ad9f
 
d1ad9f
-        if (!err) {
d1ad9f
-            got_plugin = 1;
d1ad9f
-            htmp->dlhandle = handle;
d1ad9f
-            handle = NULL;
d1ad9f
-        }
d1ad9f
+#elif defined(_WIN32)
d1ad9f
 
d1ad9f
-        if (handle != NULL) { dlclose (handle); }
d1ad9f
+static long
d1ad9f
+open_plugin_win32(struct plugin_file_handle *h, const char *filename,
d1ad9f
+                  struct errinfo *ep)
d1ad9f
+{
d1ad9f
+    h->module = LoadLibrary(filename);
d1ad9f
+    if (h == NULL) {
d1ad9f
+        Tprintf("Unable to load dll: %s\n", filename);
d1ad9f
+        k5_set_error(ep, ENOENT, _("unable to load DLL [%s]"), filename);
d1ad9f
+        return ENOENT;
d1ad9f
     }
d1ad9f
-#endif /* USE_DLOPEN */
d1ad9f
-
d1ad9f
-#ifdef _WIN32
d1ad9f
-    if (!err && (statbuf.st_mode & S_IFMT) == S_IFREG) {
d1ad9f
-        HMODULE handle = NULL;
d1ad9f
+    return 0;
d1ad9f
+}
d1ad9f
+#define open_plugin open_plugin_win32
d1ad9f
 
d1ad9f
-        handle = LoadLibrary(filepath);
d1ad9f
-        if (handle == NULL) {
d1ad9f
-            Tprintf ("Unable to load dll: %s\n", filepath);
d1ad9f
-            err = ENOENT; /* XXX */
d1ad9f
-            k5_set_error(ep, err, _("unable to load DLL [%s]"), filepath);
d1ad9f
-        }
d1ad9f
+static long
d1ad9f
+get_sym_win32(struct plugin_file_handle *h, const char *csymname,
d1ad9f
+              void **sym_out, struct errinfo *ep)
d1ad9f
+{
d1ad9f
+    LPVOID lpMsgBuf;
d1ad9f
+    DWORD dw;
d1ad9f
 
d1ad9f
-        if (!err) {
d1ad9f
-            got_plugin = 1;
d1ad9f
-            htmp->hinstPlugin = handle;
d1ad9f
-            handle = NULL;
d1ad9f
+    if (h->module == NULL)
d1ad9f
+        return ENOENT;
d1ad9f
+    *sym_out = GetProcAddress(h->module, csymname);
d1ad9f
+    if (*sym_out == NULL) {
d1ad9f
+        Tprintf("GetProcAddress(%s): %i\n", csymname, GetLastError());
d1ad9f
+        dw = GetLastError();
d1ad9f
+        if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
d1ad9f
+                          FORMAT_MESSAGE_FROM_SYSTEM,
d1ad9f
+                          NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
d1ad9f
+                          (LPTSTR)&lpMsgBuf, 0, NULL)) {
d1ad9f
+            k5_set_error(ep, ENOENT, _("unable to get DLL Symbol: %s"),
d1ad9f
+                         (char *)lpMsgBuf);
d1ad9f
+            LocalFree(lpMsgBuf);
d1ad9f
         }
d1ad9f
-
d1ad9f
-        if (handle != NULL)
d1ad9f
-            FreeLibrary(handle);
d1ad9f
-    }
d1ad9f
-#endif
d1ad9f
-
d1ad9f
-    if (!err && !got_plugin) {
d1ad9f
-        err = ENOENT;  /* no plugin or no way to load plugins */
d1ad9f
-        k5_set_error(ep, err, _("plugin unavailable: %s"), strerror(err));
d1ad9f
+        return ENOENT;
d1ad9f
     }
d1ad9f
+    return 0;
d1ad9f
+}
d1ad9f
+#define get_sym get_sym_win32
d1ad9f
 
d1ad9f
-    if (!err) {
d1ad9f
-        *h = htmp;
d1ad9f
-        htmp = NULL;  /* h takes ownership */
d1ad9f
-    }
d1ad9f
+static void
d1ad9f
+close_plugin_win32(struct plugin_file_handle *h)
d1ad9f
+{
d1ad9f
+    if (h->module != NULL)
d1ad9f
+        FreeLibrary(h->module);
d1ad9f
+}
d1ad9f
+#define close_plugin close_plugin_win32
d1ad9f
 
d1ad9f
-    free(htmp);
d1ad9f
+#else
d1ad9f
 
d1ad9f
-    return err;
d1ad9f
+static long
d1ad9f
+open_plugin_dummy(struct plugin_file_handle *h, const char *filename,
d1ad9f
+                  struct errinfo *ep)
d1ad9f
+{
d1ad9f
+    k5_set_error(ep, ENOENT, _("plugin loading unavailable"));
d1ad9f
+    return ENOENT;
d1ad9f
 }
d1ad9f
+#define open_plugin open_plugin_dummy
d1ad9f
 
d1ad9f
 static long
d1ad9f
-krb5int_get_plugin_sym (struct plugin_file_handle *h,
d1ad9f
-                        const char *csymname, int isfunc, void **ptr,
d1ad9f
-                        struct errinfo *ep)
d1ad9f
+get_sym_dummy(struct plugin_file_handle *h, const char *csymname,
d1ad9f
+              void **sym_out, struct errinfo *ep)
d1ad9f
 {
d1ad9f
-    long err = 0;
d1ad9f
-    void *sym = NULL;
d1ad9f
+    return ENOENT;
d1ad9f
+}
d1ad9f
+#define get_sym get_sym_dummy
d1ad9f
+
d1ad9f
+static void
d1ad9f
+close_plugin_dummy(struct plugin_file_handle *h)
d1ad9f
+{
d1ad9f
+}
d1ad9f
+#define close_plugin close_plugin_dummy
d1ad9f
 
d1ad9f
-#if USE_DLOPEN
d1ad9f
-    if (!err && !sym && (h->dlhandle != NULL)) {
d1ad9f
-        /* XXX Do we need to add a leading "_" to the symbol name on any
d1ad9f
-           modern platforms?  */
d1ad9f
-        sym = dlsym (h->dlhandle, csymname);
d1ad9f
-        if (sym == NULL) {
d1ad9f
-            const char *e = dlerror (); /* XXX copy and save away */
d1ad9f
-            if (e == NULL)
d1ad9f
-                e = "unknown failure";
d1ad9f
-            Tprintf ("dlsym(%s): %s\n", csymname, e);
d1ad9f
-            err = ENOENT; /* XXX */
d1ad9f
-            k5_set_error(ep, err, "%s", e);
d1ad9f
-        }
d1ad9f
-    }
d1ad9f
 #endif
d1ad9f
 
d1ad9f
-#ifdef _WIN32
d1ad9f
-    LPVOID lpMsgBuf;
d1ad9f
-    DWORD dw;
d1ad9f
+long KRB5_CALLCONV
d1ad9f
+krb5int_open_plugin(const char *filename,
d1ad9f
+                    struct plugin_file_handle **handle_out, struct errinfo *ep)
d1ad9f
+{
d1ad9f
+    long ret;
d1ad9f
+    struct plugin_file_handle *h;
d1ad9f
 
d1ad9f
-    if (!err && !sym && (h->hinstPlugin != NULL)) {
d1ad9f
-        sym = GetProcAddress(h->hinstPlugin, csymname);
d1ad9f
-        if (sym == NULL) {
d1ad9f
-            const char *e = "unable to get dll symbol"; /* XXX copy and save away */
d1ad9f
-            Tprintf ("GetProcAddress(%s): %i\n", csymname, GetLastError());
d1ad9f
-            err = ENOENT; /* XXX */
d1ad9f
-            k5_set_error(ep, err, "%s", e);
d1ad9f
-
d1ad9f
-            dw = GetLastError();
d1ad9f
-            if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
d1ad9f
-                              FORMAT_MESSAGE_FROM_SYSTEM,
d1ad9f
-                              NULL,
d1ad9f
-                              dw,
d1ad9f
-                              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
d1ad9f
-                              (LPTSTR) &lpMsgBuf,
d1ad9f
-                              0, NULL )) {
d1ad9f
-
d1ad9f
-                fprintf (stderr, "unable to get dll symbol, %s\n", (LPCTSTR)lpMsgBuf);
d1ad9f
-                LocalFree(lpMsgBuf);
d1ad9f
-            }
d1ad9f
-        }
d1ad9f
-    }
d1ad9f
-#endif
d1ad9f
+    *handle_out = NULL;
d1ad9f
 
d1ad9f
-    if (!err && (sym == NULL)) {
d1ad9f
-        err = ENOENT;  /* unimplemented */
d1ad9f
-    }
d1ad9f
+    h = calloc(1, sizeof(*h));
d1ad9f
+    if (h == NULL)
d1ad9f
+        return ENOMEM;
d1ad9f
 
d1ad9f
-    if (!err) {
d1ad9f
-        *ptr = sym;
d1ad9f
+    ret = open_plugin(h, filename, ep);
d1ad9f
+    if (ret) {
d1ad9f
+        free(h);
d1ad9f
+        return ret;
d1ad9f
     }
d1ad9f
 
d1ad9f
-    return err;
d1ad9f
+    *handle_out = h;
d1ad9f
+    return 0;
d1ad9f
 }
d1ad9f
 
d1ad9f
 long KRB5_CALLCONV
d1ad9f
-krb5int_get_plugin_data (struct plugin_file_handle *h, const char *csymname,
d1ad9f
-                         void **ptr, struct errinfo *ep)
d1ad9f
+krb5int_get_plugin_data(struct plugin_file_handle *h, const char *csymname,
d1ad9f
+                        void **sym_out, struct errinfo *ep)
d1ad9f
 {
d1ad9f
-    return krb5int_get_plugin_sym (h, csymname, 0, ptr, ep);
d1ad9f
+    return get_sym(h, csymname, sym_out, ep);
d1ad9f
 }
d1ad9f
 
d1ad9f
 long KRB5_CALLCONV
d1ad9f
-krb5int_get_plugin_func (struct plugin_file_handle *h, const char *csymname,
d1ad9f
-                         void (**ptr)(), struct errinfo *ep)
d1ad9f
+krb5int_get_plugin_func(struct plugin_file_handle *h, const char *csymname,
d1ad9f
+                        void (**sym_out)(), struct errinfo *ep)
d1ad9f
 {
d1ad9f
     void *dptr = NULL;
d1ad9f
-    long err = krb5int_get_plugin_sym (h, csymname, 1, &dptr, ep);
d1ad9f
-    if (!err) {
d1ad9f
-        /* Cast function pointers to avoid code duplication */
d1ad9f
-        *ptr = (void (*)()) dptr;
d1ad9f
-    }
d1ad9f
-    return err;
d1ad9f
+    long ret = get_sym(h, csymname, &dptr, ep);
d1ad9f
+
d1ad9f
+    if (!ret)
d1ad9f
+        *sym_out = (void (*)())dptr;
d1ad9f
+    return ret;
d1ad9f
 }
d1ad9f
 
d1ad9f
 void KRB5_CALLCONV
d1ad9f
 krb5int_close_plugin (struct plugin_file_handle *h)
d1ad9f
 {
d1ad9f
-#if USE_DLOPEN
d1ad9f
-    if (h->dlhandle != NULL) { dlclose(h->dlhandle); }
d1ad9f
-#endif
d1ad9f
-#ifdef _WIN32
d1ad9f
-    if (h->hinstPlugin != NULL) { FreeLibrary(h->hinstPlugin); }
d1ad9f
-#endif
d1ad9f
-    free (h);
d1ad9f
+    close_plugin(h);
d1ad9f
+    free(h);
d1ad9f
 }
d1ad9f
 
d1ad9f
-/* autoconf docs suggest using this preference order */
d1ad9f
-#if HAVE_DIRENT_H || USE_DIRENT_H
d1ad9f
-#include <dirent.h>
d1ad9f
-#define NAMELEN(D) strlen((D)->d_name)
d1ad9f
-#else
d1ad9f
-#ifndef _WIN32
d1ad9f
-#define dirent direct
d1ad9f
-#define NAMELEN(D) ((D)->d->namlen)
d1ad9f
-#else
d1ad9f
-#define NAMELEN(D) strlen((D)->d_name)
d1ad9f
-#endif
d1ad9f
-#if HAVE_SYS_NDIR_H
d1ad9f
-# include <sys/ndir.h>
d1ad9f
-#elif HAVE_SYS_DIR_H
d1ad9f
-# include <sys/dir.h>
d1ad9f
-#elif HAVE_NDIR_H
d1ad9f
-# include <ndir.h>
d1ad9f
-#endif
d1ad9f
-#endif
d1ad9f
-
d1ad9f
 static long
d1ad9f
 krb5int_plugin_file_handle_array_init (struct plugin_file_handle ***harray)
d1ad9f
 {
d1ad9f
@@ -619,42 +418,36 @@ krb5int_open_plugin_dirs (const char * const *dirnames,
d1ad9f
                 if (handle   != NULL) { krb5int_close_plugin (handle); }
d1ad9f
             }
d1ad9f
         } else {
d1ad9f
-            /* load all plugins in each directory */
d1ad9f
-            DIR *dir = opendir (dirnames[i]);
d1ad9f
+            char **fnames = NULL;
d1ad9f
+            int j;
d1ad9f
 
d1ad9f
-            while (dir != NULL && !err) {
d1ad9f
-                struct dirent *d = NULL;
d1ad9f
+            err = k5_dir_filenames(dirnames[i], &fnames);
d1ad9f
+            for (j = 0; !err && fnames[j] != NULL; j++) {
d1ad9f
                 char *filepath = NULL;
d1ad9f
                 struct plugin_file_handle *handle = NULL;
d1ad9f
 
d1ad9f
-                d = readdir (dir);
d1ad9f
-                if (d == NULL) { break; }
d1ad9f
-
d1ad9f
-                if ((strcmp (d->d_name, ".") == 0) ||
d1ad9f
-                    (strcmp (d->d_name, "..") == 0)) {
d1ad9f
+                if (strcmp(fnames[j], ".") == 0 ||
d1ad9f
+                    strcmp(fnames[j], "..") == 0)
d1ad9f
                     continue;
d1ad9f
-                }
d1ad9f
 
d1ad9f
-                if (!err) {
d1ad9f
-                    int len = NAMELEN (d);
d1ad9f
-                    if (asprintf(&filepath, "%s/%*s", dirnames[i], len, d->d_name) < 0) {
d1ad9f
-                        filepath = NULL;
d1ad9f
-                        err = ENOMEM;
d1ad9f
-                    }
d1ad9f
+                if (asprintf(&filepath, "%s/%s", dirnames[i], fnames[j]) < 0) {
d1ad9f
+                    filepath = NULL;
d1ad9f
+                    err = ENOMEM;
d1ad9f
                 }
d1ad9f
 
d1ad9f
-                if (!err) {
d1ad9f
-                    if (krb5int_open_plugin (filepath, &handle, ep) == 0) {
d1ad9f
-                        err = krb5int_plugin_file_handle_array_add (&h, &count, handle);
d1ad9f
-                        if (!err) { handle = NULL; }  /* h takes ownership */
d1ad9f
-                    }
d1ad9f
+                if (!err && krb5int_open_plugin(filepath, &handle, ep) == 0) {
d1ad9f
+                    err = krb5int_plugin_file_handle_array_add(&h, &count,
d1ad9f
+                                                               handle);
d1ad9f
+                    if (!err)
d1ad9f
+                        handle = NULL;  /* h takes ownership */
d1ad9f
                 }
d1ad9f
 
d1ad9f
                 free(filepath);
d1ad9f
-                if (handle    != NULL) { krb5int_close_plugin (handle); }
d1ad9f
+                if (handle != NULL)
d1ad9f
+                    krb5int_close_plugin(handle);
d1ad9f
             }
d1ad9f
 
d1ad9f
-            if (dir != NULL) { closedir (dir); }
d1ad9f
+            k5_free_filenames(fnames);
d1ad9f
         }
d1ad9f
     }
d1ad9f
 
d1ad9f
-- 
d1ad9f
2.38.1
d1ad9f