Updated documentation for 0.2 release
[mtetherd] / util.c
diff --git a/util.c b/util.c
index cc3966d..544699f 100644 (file)
--- a/util.c
+++ b/util.c
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <stdlib.h>
 #include <stdio.h>
-#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 #include <glib.h>
+#include "util.h"
+#include "plugin.h"
 
 static const char *MODULE_LIST = "/proc/modules";
+// Wait x seconds for process termination
+static const unsigned int TERMINATE_WAIT = 5;
 
 gboolean mtetherd_scan_modules(const char *module) {
-       g_message("Scanning %s", MODULE_LIST);
+       g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Scanning %s", MODULE_LIST);
 
        FILE *fp = fopen(MODULE_LIST, "r");
        if (!fp) {
@@ -34,9 +42,9 @@ gboolean mtetherd_scan_modules(const char *module) {
        gboolean found = FALSE;
        char *line = NULL;
        while (!found && getline(&line, NULL, fp) != -1) {
-               g_debug("Checking if '%s' starts with %s...", line, module);
-               if (strcmp(line, module, strlen(module)) == 0) {
-                       g_message("Found %s", module);
+               g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Checking if '%s' starts with %s...", line, module);
+               if (g_str_has_prefix(line, module)) {
+                       g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Found %s", module);
                        found = TRUE;
                }
                free(line);
@@ -46,27 +54,64 @@ gboolean mtetherd_scan_modules(const char *module) {
        return found;
 }
 
+#ifdef LAUNCH_SYNCHRONOUS
 gboolean mtetherd_launch_script(const char *command[]) {
-/*
-       const char *arg;
-       if (enable) {
-               arg = SBIN_DIR "mtetherd-usbnet-enable.sh";
-       } else {
-               arg = SBIN_DIR "mtetherd-usbnet-disable.sh";
+       if (command && command[0]) {
+               g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Launching %s", command[0]);
+               pid_t pid = fork();
+               if (pid == 0) {
+                       if (execv(command[0], (char **const) command) == -1) {
+                               exit(1);
+                       }
+               } else if (pid == -1) {
+                       g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Error forking: %s", g_strerror(errno));
+                       return FALSE;
+               } else {
+                       size_t i;
+                       for (i = 0; i < TERMINATE_WAIT; i++) {
+                               int status = 0;
+                               if (waitpid(pid, &status, WNOHANG) == -1) {
+                                       g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Error waiting for child process completion: %s", g_strerror(errno));
+                                       return FALSE;
+                               }
+                               if (WIFEXITED(status)) {
+                                       if (WEXITSTATUS(status) != 0) {
+                                               g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Child process returned error: %d", WEXITSTATUS(status));
+                                               return FALSE;
+                                       } else {
+                                               g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Child process returned ok");
+                                               return TRUE;
+                                       }
+                               } else if (WIFSIGNALED(status)) {
+                                       g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Child process killed by signal: %d", WTERMSIG(status));
+                                       return FALSE;
+                               } else {
+                                       sleep(1);
+                               }
+                       }
+                       g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Child process still running after %u seconds, ignoring", TERMINATE_WAIT);
+                       return FALSE;
+               }
        }
-       g_debug("Launching %s", arg);
-       const char *command[] = { "/usr/bin/sudo", arg, NULL };
-*/
-       pid_t pid = fork();
-       if (pid == 0) {
-               if (execv(command[0], (char **const) command) == -1) {
-                       exit(1);
+       return FALSE;
+}
+#else
+gboolean mtetherd_launch_script(const char *command[]) {
+       if (command && command[0]) {
+               g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Launching %s", command[0]);
+               pid_t pid = fork();
+               if (pid == 0) {
+                       if (execv(command[0], (char **const) command) == -1) {
+                               exit(1);
+                       }
+               } else if (pid == -1) {
+                       // error forking
+                       return FALSE;
                }
-       } else if (pid == -1) {
-               // error forking
-               return FALSE;
+               // launch ok
+               return TRUE;
        }
-       // launch ok
-       return TRUE;
+       return FALSE;
 }
+#endif