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