speechd-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] add an initial module detection algorithm


From: Christopher Brannon
Subject: [PATCH] add an initial module detection algorithm
Date: Wed, 1 Dec 2010 12:17:00 +0000

From: Trevor Saunders <address@hidden>
To: address@hidden

we simply walk through the list of files in MODULEBINDIR, and use the
files name to get the paths for that module.

Modified-by: Andrei Kholodnyi <Andrei.Kholodnyi at gmail.com>
move module detect function in module.c

put added_modules from conf and detected modules in one list and load them

comment all AddModule directives in the conf file, instead of removing them

Modified by Christopher Brannon: detect modules and call
module_add_load_request.  detect_modules performs some sanity-checking
on filenames, to insure that they name regular files and have a proper
prefix of "sd_".
---
 config/speechd.conf  |    6 ++--
 src/server/module.c  |   71 +++++++++++++++++++++++++++++++++++++++++++++++++-
 src/server/module.h  |    1 +
 src/server/speechd.c |   10 +++++++
 4 files changed, 84 insertions(+), 4 deletions(-)

diff --git a/config/speechd.conf b/config/speechd.conf
index a230785..3b19569 100644
--- a/config/speechd.conf
+++ b/config/speechd.conf
@@ -206,8 +206,8 @@ DefaultVolume 100
 #  - configuration is the path to the config file of this module,
 #    either relative (to etc/speech-dispatcher/modules/) or absolute
 
-AddModule "espeak"       "sd_espeak"   "espeak.conf"
-AddModule "festival"     "sd_festival"  "festival.conf"
+#AddModule "espeak"       "sd_espeak"   "espeak.conf"
+#AddModule "festival"     "sd_festival"  "festival.conf"
 #AddModule "flite"        "sd_flite"     "flite.conf"
 #AddModule "ivona"      "sd_ivona"    "ivona.conf"
 #AddModule "pico"        "sd_pico"     "pico.conf"
@@ -222,7 +222,7 @@ AddModule "festival"     "sd_festival"  "festival.conf"
 # DO NOT REMOVE the following line unless you have
 # a specific reason -- this is the fallback output module
 # that is only used when no other modules are in use
-AddModule "dummy"         "sd_dummy"      ""
+#AddModule "dummy"         "sd_dummy"      ""
 
 # The output module testing doesn't actually connect to anything. It
 # outputs the requested commands to standard output and reads
diff --git a/src/server/module.c b/src/server/module.c
index 7e9d23e..a1e2e42 100644
--- a/src/server/module.c
+++ b/src/server/module.c
@@ -26,13 +26,18 @@
 #include <config.h>
 #endif
 
+#include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
+#include <sys/unistd.h>
 #include <stdio.h>
+#include <dirent.h>
+#include <glib.h>
+
 #include "speechd.h"
 #include <spd_utils.h>
 #include "output.h"
-
+#include "module.h"
 
 void
 destroy_module(OutputModule *module)
@@ -43,6 +48,70 @@ destroy_module(OutputModule *module)
     g_free(module);
 }
 
+/*
+ * detect_output_modules: automatically discover all available modules.
+ * Parameters:
+ * dirname: name of the directory containing module binaries.
+ * Returns: a list of detected modules.
+ * For each file in the directory containing module binaries,
+ * add an entry to a list of discovered modules.
+ */
+GList *
+detect_output_modules(char *dirname)
+{
+    static const int FNAME_PREFIX_LENGTH = 3;
+    DIR *module_dir = opendir(dirname);
+    struct dirent *entry;
+    char **module_parameters;
+    GList *modules = NULL;
+    char *full_path;
+    struct stat fileinfo;
+    int sys_ret;
+
+    if(module_dir == NULL){
+        MSG(3, "couldn't open directory %s because of error %s\n", dirname, 
strerror(errno));
+        return NULL;
+    }
+
+    while(NULL != (entry = readdir(module_dir))){
+
+        if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
+            continue;
+        full_path = spd_get_path(entry->d_name, dirname);
+        sys_ret = stat(full_path, &fileinfo);
+        g_free(full_path);
+        if (sys_ret != 0) {
+            MSG(4, "stat failed on file %s in %s", entry->d_name, dirname);
+            continue;
+        }
+        /* Note: stat(2) dereferences symlinks. */
+        if (!S_ISREG(fileinfo.st_mode)) {
+            MSG(4, "Ignoring %s in %s; not a regular file.", entry->d_name,
+                dirname);
+            continue;
+        }
+
+        if (strncmp(entry->d_name, "sd_", FNAME_PREFIX_LENGTH)
+            || (entry->d_name[FNAME_PREFIX_LENGTH] == '\0')) {
+            MSG(1, "Module discovery ignoring %s: malformed filename.",
+                entry->d_name);
+            continue;
+        }
+
+        module_parameters = g_malloc(4 * sizeof(char *));
+        module_parameters[0] = g_strdup(entry->d_name + FNAME_PREFIX_LENGTH);
+        module_parameters[1] = g_strdup(entry->d_name);
+        module_parameters[2] = g_strdup_printf("%s.conf", 
module_parameters[0]);
+        module_parameters[3] = g_strdup_printf("%s/%s.log", 
SpeechdOptions.log_dir, module_parameters[0]);
+        modules = g_list_append(modules, module_parameters);
+
+        MSG(5,"Module name=%s being inserted into detected_modules list", 
module_parameters[0]);
+    }
+
+    closedir(module_dir);
+    return modules;
+}
+
 OutputModule*
 load_output_module(char* mod_name, char* mod_prog, char* mod_cfgfile, char* 
mod_dbgfile)
 {
diff --git a/src/server/module.h b/src/server/module.h
index cd2024d..5bbed2a 100644
--- a/src/server/module.h
+++ b/src/server/module.h
@@ -42,6 +42,7 @@ typedef struct{
     SPDVoice **voices;
 }OutputModule;
 
+GList *detect_output_modules(char *dirname);
 OutputModule* load_output_module(char* mod_name, char* mod_prog,
                                  char* mod_cfgfile, char * mod_dbgfile);
 int unload_output_module(OutputModule *module);
diff --git a/src/server/speechd.c b/src/server/speechd.c
index e0e6c94..3dff55c 100644
--- a/src/server/speechd.c
+++ b/src/server/speechd.c
@@ -657,6 +657,7 @@ void
 speechd_load_configuration(int sig)
 {
     configfile_t *configfile = NULL;
+    GList *detected_modules = NULL;
 
     /* Clean previous configuration */
     if (output_modules != NULL) {
@@ -688,6 +689,15 @@ speechd_load_configuration(int sig)
 
       /* We need to load modules here, since this is called both by 
speechd_init
        * and to handle SIGHUP. */
+      detected_modules = detect_output_modules(MODULEBINDIR);
+      while (detected_modules != NULL) {
+        char **parameters = detected_modules->data;
+        module_add_load_request(parameters[0], parameters[1], parameters[2], 
parameters[3]);
+        g_free(detected_modules->data);
+        detected_modules->data = NULL;
+        detected_modules = g_list_delete_link(detected_modules, 
detected_modules);
+      }
+
       module_load_requested_modules();
     }else{
       MSG(1, "Can't open %s", SpeechdOptions.conf_file);
-- 
1.7.3.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]