/* $Id$
* Gnome user interface
- * Copyright (C) 2004 Jan Kratochvil <project-udpforward@jankratochvil.net>
+ * Copyright (C) 2004 Jan Kratochvil <project-udpgate@jankratochvil.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <gtk/gtktogglebutton.h>
#include <string.h>
#include <gtk/gtkmain.h>
+#include <libgnomeui/gnome-app-util.h>
+
+#include "network.h"
+#include "packet.h"
/* Config: */
-#define PATHNAME_PID "/var/run/udpforward.pid"
-#define DAEMON_CHECK_INTERVAL_MS 500
+#define DAEMON_CHECK_INTERVAL_MS 100
#define PORT_RANGE_BEGIN 2048
#define PORT_RANGE_END 10240
static GtkHBox *PortHBox;
static GnomeAppBar *AppBar;
static GtkEntry *PortEntry;
+static GtkEntry *HostIPEntry;
-static pid_t daemon_pid;
-
-static gboolean is_daemon_running(void)
-{
-FILE *f;
-char buf[LINE_MAX],*got;
-int pid_int;
-
- daemon_pid=(pid_t)-1;
- if (!(f=fopen(PATHNAME_PID,"r")))
- goto err;
- got=fgets(buf,sizeof(buf),f);
- fclose(f); /* FIXME: error ignored */
- if (got!=buf) {
-err_unlink:
- unlink(PATHNAME_PID);
-err:
- return FALSE;
- }
- pid_int=atoi(buf);
- if (pid_int<=1)
- goto err_unlink;
- if (kill((pid_t)pid_int,0)) {
- if (errno==ESRCH)
- goto err_unlink;
- goto err;
- }
- daemon_pid=(pid_t)pid_int;
- return TRUE;
-}
-
static void state_start_stop(void)
{
+pid_t daemon_pid;
gboolean daemon_running;
+static gboolean last_daemon_running,last_daemon_running_set=FALSE;
+
+ daemon_pid=is_daemon_running();
+ daemon_running=((pid_t)-1!=daemon_pid);
+
+ /* Cache the result; maybe not needed. */
+ if (last_daemon_running_set && last_daemon_running==daemon_running)
+ return;
+ last_daemon_running=daemon_running;
+ last_daemon_running_set=TRUE;
- daemon_running=is_daemon_running();
gtk_widget_set_sensitive(GTK_WIDGET(ButtonStart),!daemon_running);
gtk_widget_set_sensitive(GTK_WIDGET(ButtonStop) , daemon_running);
gtk_widget_set_sensitive(GTK_WIDGET(PortHBox) ,!daemon_running);
if (daemon_running)
gnome_appbar_set_status(AppBar,
- udpforward_printf_alloca(_("udpforward daemon running as PID %d."),(int)daemon_pid));
+ udpgate_printf_alloca(_("udpgate daemon running as PID %d."),(int)daemon_pid));
else
- gnome_appbar_set_status(AppBar,_("No udpforward daemon currently running."));
+ gnome_appbar_set_status(AppBar,_("No udpgate daemon currently running."));
}
static gboolean daemon_check_timeout_func(gpointer data /* unused */)
g_return_if_fail(GTK_IS_BUTTON(button));
state_start_stop();
- if ((pid_t)-1!=daemon_pid)
+ if ((pid_t)-1!=is_daemon_running())
return;
gtk_entry_set_text(PortEntry,
- udpforward_printf_alloca("%d",(int)g_random_int_range(PORT_RANGE_BEGIN,PORT_RANGE_END)));
+ udpgate_printf_alloca("%d",(int)g_random_int_range(PORT_RANGE_BEGIN,PORT_RANGE_END)));
}
void on_AutostartCheckButton_toggled(GtkToggleButton *togglebutton,gpointer user_data)
{
g_return_if_fail(GTK_IS_BUTTON(button));
- state_start_stop();
- if ((pid_t)-1!=daemon_pid)
+ if (!optarg_port_set_string(gtk_entry_get_text(PortEntry)))
return;
+ network_start(optarg_port);
}
void on_ButtonStop_clicked(GtkButton *button,gpointer user_data)
{
-int errno_save;
-
g_return_if_fail(GTK_IS_BUTTON(button));
- state_start_stop();
- if ((pid_t)-1==daemon_pid)
- return;
- errno=0;
- kill(daemon_pid,SIGKILL);
- errno_save=errno;
- if (errno_save)
- g_warning(udpforward_printf_alloca(_("Unable to stop the daemon at PID %d: %s"),
- (int)daemon_pid,strerror(errno_save)));
+ network_stop();
}
void on_ButtonHide_clicked(GtkButton *button,gpointer user_data)
{
g_return_if_fail(GTK_IS_BUTTON(button));
- gtk_main_quit();
+ /* update config file */
+ optarg_port_set_string(gtk_entry_get_text(PortEntry));
+
+ /* Do not: gtk_main_quit();
+ * as 'App' widget will quit our gtk_main() automatically.
+ */
+ gtk_widget_destroy(GTK_WIDGET(App));
+}
+
+static void ui_gnome_network_notify_hostip(guint32 hostip_guint32)
+{
+ if (!hostip_guint32) {
+ if (is_daemon_running()==(pid_t)-1)
+ gtk_entry_set_text(HostIPEntry,_("(unknown; Start the daemon)"));
+ else
+ gtk_entry_set_text(HostIPEntry,_("(unknown; detecting...)"));
+ }
+ else {
+ gtk_entry_set_text(HostIPEntry,HOSTIP_GUINT32_TO_STRING(hostip_guint32));
+ }
+}
+
+static guint ui_gnome_g_log_handler_handler_id;
+static void ui_gnome_g_log_handler(const gchar *log_domain,GLogLevelFlags log_level,const gchar *message,gpointer user_data)
+{
+GtkWidget *dialog;
+
+ /**/ if (log_level & G_LOG_LEVEL_ERROR)
+ dialog=gnome_app_error(App,message);
+ else if (log_level & (G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING))
+ dialog=gnome_app_warning(App,message);
+ else
+ dialog=gnome_app_message(App,message);
+
+ gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);
+ g_signal_connect((gpointer)dialog,"close",G_CALLBACK(gtk_main_quit),NULL);
+ gtk_main();
+ /* 'dialog' gets destroyed automatically */
+}
+
+static void ui_gnome_interactive(void)
+{
+ gtk_main();
+ network_notify_hostip=NULL;
+ g_log_remove_handler(
+ G_LOG_DOMAIN, /* log_domain; "Captive" */
+ ui_gnome_g_log_handler_handler_id); /* handler_id */
+ network_detach();
}
/* of "ui-gnome-interface.h": */
PortHBox=GTK_HBOX(lookup_widget(GTK_WIDGET(App),"PortHBox"));
AppBar=GNOME_APPBAR(lookup_widget(GTK_WIDGET(App),"AppBar"));
PortEntry=GTK_ENTRY(lookup_widget(GTK_WIDGET(App),"PortEntry"));
+ HostIPEntry=GTK_ENTRY(lookup_widget(GTK_WIDGET(App),"HostIPEntry"));
+
+ /* ui_gnome_g_log_handler() needs 'App'. */
+ ui_gnome_g_log_handler_handler_id=g_log_set_handler(
+ G_LOG_DOMAIN, /* log_domain; "Captive" */
+ (G_LOG_LEVEL_MASK|G_LOG_FLAG_FATAL)&~(0
+ |G_LOG_LEVEL_MESSAGE
+ |G_LOG_LEVEL_INFO
+ |G_LOG_LEVEL_DEBUG), /* log_levels */
+ ui_gnome_g_log_handler, /* log_func */
+ NULL); /* user_data */
+
+ ui_gnome_network_notify_hostip(0);
+ gtk_entry_set_text(PortEntry,udpgate_printf_alloca("%d",(int)optarg_port));
gtk_widget_show_all(GTK_WIDGET(App));
g_timeout_add(
DAEMON_CHECK_INTERVAL_MS, /* interval */
daemon_check_timeout_func, /* function */
NULL); /* data; unused */
- return TRUE;
-}
-void ui_gnome_interactive(void)
-{
- gtk_main();
+ network_notify_hostip=ui_gnome_network_notify_hostip;
+
+ ui_interactive=ui_gnome_interactive;
+
+ return TRUE;
}