Fixed network setup scripts
[mtetherd] / util.c
1 /*
2   mtetherd
3   (c) 2010 Gregor Riepl <onitake@gmail.com>
4   
5   Tethering utility for Maemo
6   
7   This program is free software: you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation, either version 3 of the License, or
10   (at your option) any later version.
11   
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16   
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <sys/types.h>
26 #include <sys/wait.h>
27 #include <glib.h>
28 #include "util.h"
29 #include "plugin.h"
30
31 static const char *MODULE_LIST = "/proc/modules";
32 // Wait x seconds for process termination
33 static const unsigned int TERMINATE_WAIT = 5;
34
35 gboolean mtetherd_scan_modules(const char *module) {
36         g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Scanning %s", MODULE_LIST);
37
38         FILE *fp = fopen(MODULE_LIST, "r");
39         if (!fp) {
40                 return FALSE;
41         }
42         gboolean found = FALSE;
43         char *line = NULL;
44         while (!found && getline(&line, NULL, fp) != -1) {
45                 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Checking if '%s' starts with %s...", line, module);
46                 if (g_str_has_prefix(line, module)) {
47                         g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Found %s", module);
48                         found = TRUE;
49                 }
50                 free(line);
51                 line = NULL;
52         }
53         fclose(fp);
54         return found;
55 }
56
57 #ifdef LAUNCH_SYNCHRONOUS
58 gboolean mtetherd_launch_script(const char *command[]) {
59         if (command && command[0]) {
60                 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Launching %s", command[0]);
61                 pid_t pid = fork();
62                 if (pid == 0) {
63                         if (execv(command[0], (char **const) command) == -1) {
64                                 exit(1);
65                         }
66                 } else if (pid == -1) {
67                         g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Error forking: %s", g_strerror(errno));
68                         return FALSE;
69                 } else {
70                         size_t i;
71                         for (i = 0; i < TERMINATE_WAIT; i++) {
72                                 int status = 0;
73                                 if (waitpid(pid, &status, WNOHANG) == -1) {
74                                         g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Error waiting for child process completion: %s", g_strerror(errno));
75                                         return FALSE;
76                                 }
77                                 if (WIFEXITED(status)) {
78                                         if (WEXITSTATUS(status) != 0) {
79                                                 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Child process returned error: %d", WEXITSTATUS(status));
80                                                 return FALSE;
81                                         } else {
82                                                 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Child process returned ok");
83                                                 return TRUE;
84                                         }
85                                 } else if (WIFSIGNALED(status)) {
86                                         g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Child process killed by signal: %d", WTERMSIG(status));
87                                         return FALSE;
88                                 } else {
89                                         sleep(1);
90                                 }
91                         }
92                         g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Child process still running after %u seconds, ignoring", TERMINATE_WAIT);
93                         return FALSE;
94                 }
95         }
96         return FALSE;
97 }
98 #else
99 gboolean mtetherd_launch_script(const char *command[]) {
100         if (command && command[0]) {
101                 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Launching %s", command[0]);
102                 pid_t pid = fork();
103                 if (pid == 0) {
104                         if (execv(command[0], (char **const) command) == -1) {
105                                 exit(1);
106                         }
107                 } else if (pid == -1) {
108                         // error forking
109                         return FALSE;
110                 }
111                 // launch ok
112                 return TRUE;
113         }
114         return FALSE;
115 }
116 #endif
117