From e40d21df800c7336c1a2f3a4865f88b22bc96b2d Mon Sep 17 00:00:00 2001 From: "Alexey A. Smirnov" Date: Sat, 21 Nov 2009 02:23:35 +0500 Subject: added loading plugins from XDG_LOCAL_HOME dir Signed-off-by: Alexey A. Smirnov --- plugins.c | 160 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 95 insertions(+), 65 deletions(-) (limited to 'plugins.c') diff --git a/plugins.c b/plugins.c index 72f6df3c..27e44fd5 100644 --- a/plugins.c +++ b/plugins.c @@ -355,84 +355,114 @@ plug_load_all (void) { #endif const char *conf_blacklist_plugins = conf_get_str ("blacklist_plugins", ""); mutex = mutex_create (); + struct dirent **namelist; + const char *dirname = LIBDIR "/deadbeef"; - struct dirent **namelist = NULL; - int n = scandir (dirname, &namelist, NULL, alphasort); - if (n < 0) - { - if (namelist) { - free (namelist); + + char *xdg_local_home = getenv ("XDG_LOCAL_HOME"); + char xdg_plugin_dir[1024]; + + if (xdg_local_home) { + strcpy (xdg_plugin_dir, xdg_local_home); + } else { + char *homedir = getenv ("HOME"); + + if (!homedir) { + fprintf (stderr, "warning: unable to find home directory\n"); + xdg_plugin_dir[0] = '\0'; + } else { + if (snprintf (xdg_plugin_dir, sizeof (xdg_plugin_dir), + "%s/.local/lib/deadbeef", homedir) > sizeof (xdg_plugin_dir)) { + fprintf (stderr, "warning: XDG_LOCAL_HOME value is too long: %s. Ignoring.", xdg_local_home); + xdg_plugin_dir[0] = '\0'; + } } - return; // not a dir or no read access } - else - { - int i; - for (i = 0; i < n; i++) + + const char *plugins_dirs[] = { dirname, xdg_plugin_dir, NULL }; + + int k = 0, n; + + while (plugins_dirs[k]) { + namelist = NULL; + n = scandir (plugins_dirs[k], &namelist, NULL, alphasort); + if (n < 0) + { + if (namelist) { + free (namelist); + } + return; // not a dir or no read access + } + else { - // no hidden files - if (namelist[i]->d_name[0] != '.') + int i; + for (i = 0; i < n; i++) { - int l = strlen (namelist[i]->d_name); - if (l < 3) { - continue; - } - if (strcasecmp (&namelist[i]->d_name[l-3], ".so")) { - continue; - } - char d_name[256]; - memcpy (d_name, namelist[i]->d_name, l+1); - // no blacklisted - const uint8_t *p = conf_blacklist_plugins; - while (*p) { - const uint8_t *e = p; - while (*e && *e > 0x20) { - e++; + // no hidden files + if (namelist[i]->d_name[0] != '.') + { + int l = strlen (namelist[i]->d_name); + if (l < 3) { + continue; } - if (l-3 == e-p) { - if (!strncmp (p, d_name, e-p)) { - p = NULL; - break; + if (strcasecmp (&namelist[i]->d_name[l-3], ".so")) { + continue; + } + char d_name[256]; + memcpy (d_name, namelist[i]->d_name, l+1); + // no blacklisted + const uint8_t *p = conf_blacklist_plugins; + while (*p) { + const uint8_t *e = p; + while (*e && *e > 0x20) { + e++; + } + if (l-3 == e-p) { + if (!strncmp (p, d_name, e-p)) { + p = NULL; + break; + } + } + p = e; + while (*p && *p <= 0x20) { + p++; } } - p = e; - while (*p && *p <= 0x20) { - p++; + if (!p) { + fprintf (stderr, "plugin %s is blacklisted in config file\n", d_name); + continue; + } + char fullname[1024]; + strcpy (fullname, plugins_dirs[k]); + strncat (fullname, "/", 1024); + strncat (fullname, d_name, 1024); + printf ("loading plugin %s\n", d_name); + void *handle = dlopen (fullname, RTLD_NOW); + if (!handle) { + fprintf (stderr, "dlopen error: %s\n", dlerror ()); + continue; } - } - if (!p) { - fprintf (stderr, "plugin %s is blacklisted in config file\n", d_name); - continue; - } - char fullname[1024]; - strcpy (fullname, dirname); - strncat (fullname, "/", 1024); - strncat (fullname, d_name, 1024); - printf ("loading plugin %s\n", d_name); - void *handle = dlopen (fullname, RTLD_NOW); - if (!handle) { - fprintf (stderr, "dlopen error: %s\n", dlerror ()); - continue; - } - d_name[l-3] = 0; - printf ("module name is %s\n", d_name); - strcat (d_name, "_load"); - DB_plugin_t *(*plug_load)(DB_functions_t *api) = dlsym (handle, d_name); - if (!plug_load) { - fprintf (stderr, "dlsym error: %s\n", dlerror ()); - dlclose (handle); - continue; - } - if (plug_init_plugin (plug_load, handle) < 0) { d_name[l-3] = 0; - fprintf (stderr, "plugin %s is incompatible with current version of deadbeef, please upgrade the plugin\n", d_name); - dlclose (handle); - continue; + printf ("module name is %s\n", d_name); + strcat (d_name, "_load"); + DB_plugin_t *(*plug_load)(DB_functions_t *api) = dlsym (handle, d_name); + if (!plug_load) { + fprintf (stderr, "dlsym error: %s\n", dlerror ()); + dlclose (handle); + continue; + } + if (plug_init_plugin (plug_load, handle) < 0) { + d_name[l-3] = 0; + fprintf (stderr, "plugin %s is incompatible with current version of deadbeef, please upgrade the plugin\n", d_name); + dlclose (handle); + continue; + } } + free (namelist[i]); } - free (namelist[i]); + free (namelist); } - free (namelist); + ++k; } // load all compiled-in modules #define PLUG(n) extern DB_plugin_t * n##_load (DB_functions_t *api); -- cgit v1.2.3 From 46742cfc009d004e71e9ef211a78e14ae23986e2 Mon Sep 17 00:00:00 2001 From: Alexey Yakovenko Date: Sat, 21 Nov 2009 11:19:13 +0100 Subject: fixed possible memleak in plug_load_all --- plugins.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) (limited to 'plugins.c') diff --git a/plugins.c b/plugins.c index 27e44fd5..e4b41c27 100644 --- a/plugins.c +++ b/plugins.c @@ -355,9 +355,8 @@ plug_load_all (void) { #endif const char *conf_blacklist_plugins = conf_get_str ("blacklist_plugins", ""); mutex = mutex_create (); - struct dirent **namelist; - const char *dirname = LIBDIR "/deadbeef"; + struct dirent **namelist = NULL; char *xdg_local_home = getenv ("XDG_LOCAL_HOME"); char xdg_plugin_dir[1024]; @@ -368,13 +367,14 @@ plug_load_all (void) { char *homedir = getenv ("HOME"); if (!homedir) { - fprintf (stderr, "warning: unable to find home directory\n"); - xdg_plugin_dir[0] = '\0'; - } else { - if (snprintf (xdg_plugin_dir, sizeof (xdg_plugin_dir), - "%s/.local/lib/deadbeef", homedir) > sizeof (xdg_plugin_dir)) { + fprintf (stderr, "plug_load_all: warning: unable to find home directory\n"); + xdg_plugin_dir[0] = 0; + } + else { + int written = snprintf (xdg_plugin_dir, sizeof (xdg_plugin_dir), "%s/.local/lib/deadbeef", homedir); + if (written > sizeof (xdg_plugin_dir)) { fprintf (stderr, "warning: XDG_LOCAL_HOME value is too long: %s. Ignoring.", xdg_local_home); - xdg_plugin_dir[0] = '\0'; + xdg_plugin_dir[0] = 0; } } } @@ -384,8 +384,13 @@ plug_load_all (void) { int k = 0, n; while (plugins_dirs[k]) { + const char *plugdir = plugins_dirs[k++]; + if (!(*plugdir)) { + continue; + } + fprintf (stderr, "loading plugins from %s\n", plugdir); namelist = NULL; - n = scandir (plugins_dirs[k], &namelist, NULL, alphasort); + n = scandir (plugdir, &namelist, NULL, alphasort); if (n < 0) { if (namelist) { @@ -399,14 +404,14 @@ plug_load_all (void) { for (i = 0; i < n; i++) { // no hidden files - if (namelist[i]->d_name[0] != '.') + while (namelist[i]->d_name[0] != '.') { int l = strlen (namelist[i]->d_name); if (l < 3) { - continue; + break; } if (strcasecmp (&namelist[i]->d_name[l-3], ".so")) { - continue; + break; } char d_name[256]; memcpy (d_name, namelist[i]->d_name, l+1); @@ -430,17 +435,17 @@ plug_load_all (void) { } if (!p) { fprintf (stderr, "plugin %s is blacklisted in config file\n", d_name); - continue; + break; } char fullname[1024]; - strcpy (fullname, plugins_dirs[k]); + strcpy (fullname, plugdir); strncat (fullname, "/", 1024); strncat (fullname, d_name, 1024); printf ("loading plugin %s\n", d_name); void *handle = dlopen (fullname, RTLD_NOW); if (!handle) { fprintf (stderr, "dlopen error: %s\n", dlerror ()); - continue; + break; } d_name[l-3] = 0; printf ("module name is %s\n", d_name); @@ -449,20 +454,20 @@ plug_load_all (void) { if (!plug_load) { fprintf (stderr, "dlsym error: %s\n", dlerror ()); dlclose (handle); - continue; + break; } if (plug_init_plugin (plug_load, handle) < 0) { d_name[l-3] = 0; fprintf (stderr, "plugin %s is incompatible with current version of deadbeef, please upgrade the plugin\n", d_name); dlclose (handle); - continue; + break; } + break; } free (namelist[i]); } free (namelist); } - ++k; } // load all compiled-in modules #define PLUG(n) extern DB_plugin_t * n##_load (DB_functions_t *api); -- cgit v1.2.3