Added sudo scripts for enabling and disabling USB networking
[mtetherd] / status.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 <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <pwd.h>
26 #include <sys/types.h>
27 #include <gtk/gtk.h>
28 #include <hildon/hildon.h>
29
30 #include "status.h"
31
32 #define MTETHERD_STATUS_PLUGIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, TYPE_MTETHERD_STATUS_PLUGIN, MTetherDStatusPluginPrivate))
33
34 struct _MTetherDStatusPluginPrivate {
35         GtkWidget *button;
36         gboolean neton;
37 };
38
39 HD_DEFINE_PLUGIN_MODULE(MTetherDStatusPlugin, mtetherd_status_plugin, HD_TYPE_STATUS_MENU_ITEM);
40
41 static void mtetherd_status_plugin_class_finalize(MTetherDStatusPluginClass *klass) { }
42
43 static void mtetherd_status_plugin_class_init(MTetherDStatusPluginClass *klass) {
44         g_type_class_add_private(klass, sizeof(MTetherDStatusPluginPrivate));
45 }
46
47 static gboolean get_usbnet_enabled(MTetherDStatusPlugin *plugin) {
48         FILE *fp = fopen("/proc/modules", "r");
49         if (!fp) {
50                 // fallback (useless?)
51                 return plugin->priv->neton;
52         }
53         gboolean found = FALSE;
54         char *line = NULL;
55         while (!found && getline(&line, NULL, fp) != -1) {
56                 if (strncmp(line, "g_ether", 7) == 0) {
57                         found = TRUE;
58                 }
59                 free(line);
60                 line = NULL;
61         }
62         fclose(fp);
63         return found;
64 }
65
66 static void set_button_text(GtkWidget *button, gboolean enabled) {
67         if (enabled) {
68                 gtk_button_set_label(GTK_BUTTON(button), "Disable USB Networking");
69         } else {
70                 gtk_button_set_label(GTK_BUTTON(button), "Enable USB Networking");
71         }
72 }
73
74 static gboolean launch_usbnet_script(gboolean enable) {
75         const char *arg;
76         if (enable) {
77                 arg = "/usr/sbin/mtetherd-usbnet-enable.sh";
78         } else {
79                 arg = "/usr/sbin/mtetherd-usbnet-disable.sh";
80         }
81         const char *command[] = { "/usr/bin/sudo", arg, NULL };
82         pid_t pid = fork();
83         if (pid == 0) {
84                 if (execv(command[0], (char **const) command) == -1) {
85                         exit(1);
86                 }
87         } else if (pid == -1) {
88                 // error forking
89                 return FALSE;
90         }
91         // launch ok
92         return TRUE;
93 }
94
95 static void enable_usb_net_clicked(GtkWidget *button, gpointer user) {
96         MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(user);
97
98         if (button == plugin->priv->button) {
99                 gboolean enabled = get_usbnet_enabled(plugin);
100                 set_button_text(plugin->priv->button, enabled);
101                 if (enabled) {
102                         if (launch_usbnet_script(FALSE)) {
103                                 // launch ok
104                                 plugin->priv->neton = FALSE;
105                         }
106                 } else {
107                         if (launch_usbnet_script(TRUE)) {
108                                 plugin->priv->neton = TRUE;
109                         }
110                 }
111         }
112 }
113
114 static void mtetherd_status_plugin_init(MTetherDStatusPlugin *plugin) {
115         plugin->priv = MTETHERD_STATUS_PLUGIN_GET_PRIVATE(plugin);
116
117         plugin->priv->neton = FALSE;
118         plugin->priv->button = gtk_button_new();
119         set_button_text(plugin->priv->button, plugin->priv->neton);
120         g_signal_connect(plugin->priv->button, "clicked", G_CALLBACK(enable_usb_net_clicked), plugin);
121         gtk_container_add(GTK_CONTAINER(plugin), plugin->priv->button);
122         gtk_widget_show_all(plugin->priv->button);
123         gtk_widget_show(GTK_WIDGET(plugin));
124 }
125