Basic runnable version; no functionality yet.
[udpgate.git] / src / ui-gnome.c
1 /* $Id$
2  * Gnome user interface
3  * Copyright (C) 2004 Jan Kratochvil <project-udpforward@jankratochvil.net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; exactly version 2 of June 1991 is required
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19
20 #include "config.h"
21
22 #include "ui-gnome.h"   /* self */
23 #include <glib/gmessages.h>
24 #include "main.h"
25 #include <libgnomeui/gnome-app.h>
26 #include <sys/types.h>
27 #include <signal.h>
28 #include <stdio.h>
29 #include <errno.h>
30 #include <libgnomeui/gnome-appbar.h>
31 #include <gtk/gtkbutton.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <gtk/gtkentry.h>
35 #include <gtk/gtktogglebutton.h>
36 #include <string.h>
37 #include <gtk/gtkmain.h>
38
39
40 /* Config: */
41 #define PATHNAME_PID "/var/run/udpforward.pid"
42 #define DAEMON_CHECK_INTERVAL_MS 500
43 #define PORT_RANGE_BEGIN 2048
44 #define PORT_RANGE_END 10240
45
46
47 static GnomeApp *App;
48 static GtkButton *ButtonStart;
49 static GtkButton *ButtonStop;
50 static GtkHBox *PortHBox;
51 static GnomeAppBar *AppBar;
52 static GtkEntry *PortEntry;
53
54
55 static pid_t daemon_pid;
56
57 static gboolean is_daemon_running(void)
58 {
59 FILE *f;
60 char buf[LINE_MAX],*got;
61 int pid_int;
62
63         daemon_pid=(pid_t)-1;
64         if (!(f=fopen(PATHNAME_PID,"r")))
65                 goto err;
66         got=fgets(buf,sizeof(buf),f);
67         fclose(f);      /* FIXME: error ignored */
68         if (got!=buf) {
69 err_unlink:
70                 unlink(PATHNAME_PID);
71 err:
72                 return FALSE;
73                 }
74         pid_int=atoi(buf);
75         if (pid_int<=1)
76                 goto err_unlink;
77         if (kill((pid_t)pid_int,0)) {
78                 if (errno==ESRCH)
79                         goto err_unlink;
80                 goto err;
81                 }
82         daemon_pid=(pid_t)pid_int;
83         return TRUE;
84 }
85
86 static void state_start_stop(void)
87 {
88 gboolean daemon_running;
89
90         daemon_running=is_daemon_running();
91         gtk_widget_set_sensitive(GTK_WIDGET(ButtonStart),!daemon_running);
92         gtk_widget_set_sensitive(GTK_WIDGET(ButtonStop) , daemon_running);
93         gtk_widget_set_sensitive(GTK_WIDGET(PortHBox)   ,!daemon_running);
94         if (daemon_running)
95                 gnome_appbar_set_status(AppBar,
96                                 udpforward_printf_alloca(_("udpforward daemon running as PID %d."),(int)daemon_pid));
97         else
98                 gnome_appbar_set_status(AppBar,_("No udpforward daemon currently running."));
99 }
100
101 static gboolean daemon_check_timeout_func(gpointer data /* unused */)
102 {
103         state_start_stop();
104         return TRUE;    /* continue running */
105 }
106
107 void on_PortButtonRandom_clicked(GtkButton *button,gpointer user_data)
108 {
109         g_return_if_fail(GTK_IS_BUTTON(button));
110
111         state_start_stop();
112         if ((pid_t)-1!=daemon_pid)
113                 return;
114         gtk_entry_set_text(PortEntry,
115                         udpforward_printf_alloca("%d",(int)g_random_int_range(PORT_RANGE_BEGIN,PORT_RANGE_END)));
116 }
117
118 void on_AutostartCheckButton_toggled(GtkToggleButton *togglebutton,gpointer user_data)
119 {
120         g_return_if_fail(GTK_IS_TOGGLE_BUTTON(togglebutton));
121 }
122
123 void on_ButtonStart_clicked(GtkButton *button,gpointer user_data)
124 {
125         g_return_if_fail(GTK_IS_BUTTON(button));
126
127         state_start_stop();
128         if ((pid_t)-1!=daemon_pid)
129                 return;
130 }
131
132 void on_ButtonStop_clicked(GtkButton *button,gpointer user_data)
133 {
134 int errno_save;
135
136         g_return_if_fail(GTK_IS_BUTTON(button));
137
138         state_start_stop();
139         if ((pid_t)-1==daemon_pid)
140                 return;
141         errno=0;
142         kill(daemon_pid,SIGKILL);
143         errno_save=errno;
144         if (errno_save) 
145                 g_warning(udpforward_printf_alloca(_("Unable to stop the daemon at PID %d: %s"),
146                                 (int)daemon_pid,strerror(errno_save)));
147 }
148
149 void on_ButtonHide_clicked(GtkButton *button,gpointer user_data)
150 {
151         g_return_if_fail(GTK_IS_BUTTON(button));
152
153         gtk_main_quit();
154 }
155
156 /* of "ui-gnome-interface.h": */
157 GtkWidget *create_App(void);
158 /* of "ui-gnome-support.h": */
159 GtkWidget *lookup_widget(GtkWidget *widget,const gchar *widget_name);
160
161 gboolean ui_gnome_init(void)
162 {
163         App=GNOME_APP(create_App());
164
165         ButtonStart=GTK_BUTTON(lookup_widget(GTK_WIDGET(App),"ButtonStart"));
166         ButtonStop=GTK_BUTTON(lookup_widget(GTK_WIDGET(App),"ButtonStop"));
167         PortHBox=GTK_HBOX(lookup_widget(GTK_WIDGET(App),"PortHBox"));
168         AppBar=GNOME_APPBAR(lookup_widget(GTK_WIDGET(App),"AppBar"));
169         PortEntry=GTK_ENTRY(lookup_widget(GTK_WIDGET(App),"PortEntry"));
170
171         gtk_widget_show_all(GTK_WIDGET(App));
172         g_timeout_add(
173                         DAEMON_CHECK_INTERVAL_MS,       /* interval */
174                         daemon_check_timeout_func,      /* function */
175                         NULL);  /* data; unused */
176         return TRUE;
177 }
178
179 void ui_gnome_interactive(void)
180 {
181         gtk_main();
182 }