Basic runnable version; no functionality yet.
authorlace <>
Sun, 9 May 2004 21:55:16 +0000 (21:55 +0000)
committerlace <>
Sun, 9 May 2004 21:55:16 +0000 (21:55 +0000)
configure.ac
src/main.c
src/ui-gnome.c
src/ui-gnome.glade
src/ui-gnome.h

index af13c21..d6cc911 100644 (file)
@@ -120,6 +120,37 @@ AH_BOTTOM([
 #include <glib/gtypes.h>       /* for 'gchar' */
 #define G_LOG_DOMAIN ((const gchar *)"UDPForward")
 
+/**
+ * udpforward_printf_alloca:
+ * @format: Format string. See the sprintf() documentation.
+ * @args...: Arguments for @format. See the sprintf() documentation.
+ *
+ * Format the given format string @format as in sprintf().
+ * Output buffer is allocated automatically and it does not need to be deallocated
+ * manually as it is managed by g_alloca().
+ *
+ * @Returns: Formatted output string located in g_alloca() memory.
+ */
+#define udpforward_printf_alloca(format,args...) ({ \
+               gsize _udpforward_printf_alloca_size=udpforward_nv_printf_string_upper_bound((format) , ## args); \
+               gchar *_udpforward_printf_alloca_r=g_alloca(_udpforward_printf_alloca_size); \
+               g_snprintf(_udpforward_printf_alloca_r,_udpforward_printf_alloca_size,(format) , ## args); \
+               (const gchar *)_udpforward_printf_alloca_r; \
+               })
+#include <stdarg.h>
+#include <glib/gmessages.h>    /* for g_printf_string_upper_bound() */
+static inline gsize udpforward_nv_printf_string_upper_bound(const gchar *format,...) G_GNUC_PRINTF(1,0) G_GNUC_UNUSED;
+static inline gsize udpforward_nv_printf_string_upper_bound(const gchar *format,...)
+{
+va_list ap;
+gsize r;
+
+       va_start(ap,format);
+       r=g_printf_string_upper_bound(format,ap);
+       va_end(ap);
+       return r;
+}
+
 #endif /* !_UDPFORWARD_CONFIG_H */
 ])
 
index e69de29..aba413b 100644 (file)
@@ -0,0 +1,187 @@
+/* $Id$
+ * UDP forwarding utility
+ * Copyright (C) 2004 Jan Kratochvil <project-udpforward@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
+ * the Free Software Foundation; exactly version 2 of June 1991 is required
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "config.h"
+
+#include <glib/gmessages.h>
+#include <popt.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <glib/gutils.h>
+#include <string.h>
+#include <setjmp.h>
+#include <unistd.h>
+#include <libgnome/gnome-program.h>
+#include <libgnomeui/gnome-ui-init.h>
+
+#include "ui-gnome.h"
+
+
+int optarg_verbose;
+static int optarg_text;
+
+static const struct poptOption popt_table[]={
+
+#define UDPFORWARD_POPT(shortname,longname,argInfoP,argP,valP,descripP,argDescripP) \
+               { \
+                       longName: (longname), \
+                       shortName: (shortname), \
+                       argInfo: (argInfoP)|(!(valP) ? 0 : POPT_ARG_VAL), \
+                       arg: (void *)argP, \
+                       val: (valP), \
+                       descrip: (descripP), \
+                       argDescrip: (argDescripP), \
+               }
+
+               UDPFORWARD_POPT(0  ,"text"            ,POPT_ARG_NONE  ,&optarg_text   ,0,
+                               N_("Disable Gnome UI; --text must be first argument"),NULL),
+               UDPFORWARD_POPT('v',"verbose"         ,POPT_ARG_NONE  ,&optarg_verbose,0,N_("Display additional debug information"),NULL),
+
+#undef UDPFORWARD_POPT
+               POPT_TABLEEND
+               };
+
+static const struct poptOption popt_table_autohelp[]={
+               { NULL,'\0',POPT_ARG_INCLUDE_TABLE,(struct poptOption *)&popt_table,0,PACKAGE },
+               POPT_AUTOHELP
+               POPT_TABLEEND
+               };
+
+
+static jmp_buf gnome_init_atexit_jmpbuf;
+static gboolean gnome_init_atexit_disable;
+
+static void gnome_init_atexit_handler(void)
+{
+       if (gnome_init_atexit_disable)
+               return;
+
+       longjmp(gnome_init_atexit_jmpbuf,1);
+       g_assert_not_reached();
+       _exit(EXIT_FAILURE);
+}
+
+gboolean gnome_init_g_log_handler_hit;
+static void gnome_init_g_log_handler(const gchar *log_domain,GLogLevelFlags log_level,const gchar *message,gpointer user_data)
+{
+       gnome_init_g_log_handler_hit=TRUE;
+       g_log_default_handler(log_domain,log_level,message,user_data);
+}
+
+int main(int argc,char **argv)
+{
+poptContext context;
+int errint;
+gboolean is_interactive;
+gboolean no_gnome;
+
+#if 0
+       g_log_set_always_fatal(~(0
+                       |G_LOG_LEVEL_MESSAGE
+                       |G_LOG_LEVEL_INFO
+                       |G_LOG_LEVEL_DEBUG
+                       ));
+#endif
+
+       /* Initialize the i18n stuff */
+       setlocale(LC_ALL,"");
+       bindtextdomain(PACKAGE,LOCALEDIR);
+       textdomain(PACKAGE);
+
+       if (argv[1] && !strcmp(argv[1],"--text"))
+               optarg_text=1;
+
+       no_gnome=(optarg_text || !getenv("DISPLAY") || !*getenv("DISPLAY"));
+
+       if (no_gnome) {
+               context=poptGetContext(
+                               PACKAGE,        /* name */
+                               argc,(/*en-const*/const char **)argv,   /* argc,argv */
+                               popt_table_autohelp,    /* options */
+                               POPT_CONTEXT_POSIXMEHARDER);    /* flags; && !POPT_CONTEXT_KEEP_FIRST */
+               if (context==NULL) {
+                       g_assert_not_reached(); /* argument recognization args_error */
+                       return EXIT_FAILURE;
+                       }
+               errint=poptReadDefaultConfig(context,
+                               TRUE);  /* useEnv */
+               if (errint!=0) {
+                       g_assert_not_reached(); /* argument recognization args_error */
+                       return EXIT_FAILURE;
+                       }
+               errint=poptGetNextOpt(context);
+               if (errint!=-1) {
+                       g_assert_not_reached(); /* some non-callbacked argument reached */
+                       return EXIT_FAILURE;
+                       }
+               if (poptPeekArg(context)) {
+                       g_error(_("No arguments expected"));
+                       return EXIT_FAILURE;
+                       }
+               }
+       else {
+GnomeProgram *gnome_program;
+guint handler_id;
+
+               gnome_init_atexit_disable=FALSE;
+               g_atexit(gnome_init_atexit_handler);
+               gnome_init_g_log_handler_hit=FALSE;
+               handler_id=g_log_set_handler(
+                               "Gtk",  /* log_domain */
+                               G_LOG_LEVEL_WARNING,    /* log_levels */
+                               gnome_init_g_log_handler,       /* log_func */
+                               NULL);  /* user_data */
+               if (!setjmp(gnome_init_atexit_jmpbuf))
+                       gnome_program=gnome_program_init(PACKAGE,VERSION,LIBGNOMEUI_MODULE,argc,argv,
+                                       GNOME_PARAM_POPT_TABLE,popt_table,
+                                       GNOME_PARAM_POPT_FLAGS,(int)POPT_CONTEXT_POSIXMEHARDER,
+                                       NULL);
+               else {
+                       no_gnome=TRUE;
+                       /* No message: (captive-install-acquire:3693): Gtk-WARNING **: cannot open display:
+                        * was reported, probably only '--help' message was shown.
+                        */
+                       if (!gnome_init_g_log_handler_hit)
+                               exit(EXIT_SUCCESS);
+                       }
+               gnome_init_atexit_disable=TRUE;
+               g_log_remove_handler(
+                               "Gtk",  /* log_domain */
+                               handler_id);    /* handler_id */
+               }
+
+       is_interactive=(1
+/*                     && ! optarg_scan_path_list
+                       && ! optarg_scan_disks_quick
+                       && ! optarg_scan_disks 
+                       && ! optarg_microsoft_com */ );
+
+       /* Initialize UI here to catch all GLog errors below. */
+       if (is_interactive
+                       && (no_gnome || !ui_gnome_init())
+/*                     && !ui_line_init()*/)
+               g_error(_("No UI interface could be initialized"));
+
+       if (!is_interactive)
+               /*scan_batch()*/;
+       else
+               ui_gnome_interactive();
+
+       return EXIT_SUCCESS;
+}
index da3be9a..38a8786 100644 (file)
 #include "ui-gnome.h"  /* self */
 #include <glib/gmessages.h>
 #include "main.h"
+#include <libgnomeui/gnome-app.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <stdio.h>
+#include <errno.h>
+#include <libgnomeui/gnome-appbar.h>
+#include <gtk/gtkbutton.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtktogglebutton.h>
+#include <string.h>
+#include <gtk/gtkmain.h>
+
+
+/* Config: */
+#define PATHNAME_PID "/var/run/udpforward.pid"
+#define DAEMON_CHECK_INTERVAL_MS 500
+#define PORT_RANGE_BEGIN 2048
+#define PORT_RANGE_END 10240
 
 
 static GnomeApp *App;
+static GtkButton *ButtonStart;
+static GtkButton *ButtonStop;
+static GtkHBox *PortHBox;
+static GnomeAppBar *AppBar;
+static GtkEntry *PortEntry;
+
+
+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)
+{
+gboolean daemon_running;
 
+       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));
+       else
+               gnome_appbar_set_status(AppBar,_("No udpforward daemon currently running."));
+}
+
+static gboolean daemon_check_timeout_func(gpointer data /* unused */)
+{
+       state_start_stop();
+       return TRUE;    /* continue running */
+}
+
+void on_PortButtonRandom_clicked(GtkButton *button,gpointer user_data)
+{
+       g_return_if_fail(GTK_IS_BUTTON(button));
+
+       state_start_stop();
+       if ((pid_t)-1!=daemon_pid)
+               return;
+       gtk_entry_set_text(PortEntry,
+                       udpforward_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_TOGGLE_BUTTON(togglebutton));
+}
+
+void on_ButtonStart_clicked(GtkButton *button,gpointer user_data)
+{
+       g_return_if_fail(GTK_IS_BUTTON(button));
+
+       state_start_stop();
+       if ((pid_t)-1!=daemon_pid)
+               return;
+}
+
+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)));
+}
+
+void on_ButtonHide_clicked(GtkButton *button,gpointer user_data)
+{
+       g_return_if_fail(GTK_IS_BUTTON(button));
+
+       gtk_main_quit();
+}
 
 /* of "ui-gnome-interface.h": */
 GtkWidget *create_App(void);
 /* of "ui-gnome-support.h": */
 GtkWidget *lookup_widget(GtkWidget *widget,const gchar *widget_name);
 
-void ui_gnome_init(void)
+gboolean ui_gnome_init(void)
 {
        App=GNOME_APP(create_App());
+
+       ButtonStart=GTK_BUTTON(lookup_widget(GTK_WIDGET(App),"ButtonStart"));
+       ButtonStop=GTK_BUTTON(lookup_widget(GTK_WIDGET(App),"ButtonStop"));
+       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"));
+
        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();
 }
index d04fa08..5d5de22 100644 (file)
@@ -112,6 +112,7 @@ Generally you cannot use this program in firewalled networks although try to ask
                      <property name="label" translatable="yes">Try random one</property>
                      <property name="use_underline">True</property>
                      <property name="relief">GTK_RELIEF_NORMAL</property>
+                     <signal name="clicked" handler="on_PortButtonRandom_clicked" last_modification_time="Sun, 09 May 2004 16:50:55 GMT"/>
                    </widget>
                    <packing>
                      <property name="padding">0</property>
@@ -186,6 +187,7 @@ Generally you cannot use this program in firewalled networks although try to ask
                  <property name="active">False</property>
                  <property name="inconsistent">False</property>
                  <property name="draw_indicator">True</property>
+                 <signal name="toggled" handler="on_AutostartCheckButton_toggled" after="yes" last_modification_time="Sun, 09 May 2004 16:51:15 GMT"/>
                </widget>
                <packing>
                  <property name="left_attach">1</property>
@@ -261,9 +263,10 @@ Generally you cannot use this program in firewalled networks although try to ask
                  <property name="can_default">True</property>
                  <property name="can_focus">True</property>
                  <property name="relief">GTK_RELIEF_NORMAL</property>
+                 <signal name="clicked" handler="on_ButtonStart_clicked" last_modification_time="Sun, 09 May 2004 16:49:20 GMT"/>
 
                  <child>
-                   <widget class="GtkAlignment" id="alignment1">
+                   <widget class="GtkAlignment" id="ButtonStartAlignment">
                      <property name="visible">True</property>
                      <property name="xalign">0.5</property>
                      <property name="yalign">0.5</property>
@@ -271,13 +274,13 @@ Generally you cannot use this program in firewalled networks although try to ask
                      <property name="yscale">0</property>
 
                      <child>
-                       <widget class="GtkHBox" id="hbox1">
+                       <widget class="GtkHBox" id="ButtonStartHBox">
                          <property name="visible">True</property>
                          <property name="homogeneous">False</property>
                          <property name="spacing">2</property>
 
                          <child>
-                           <widget class="GtkImage" id="image1">
+                           <widget class="GtkImage" id="ButtonStartImage">
                              <property name="visible">True</property>
                              <property name="stock">gtk-execute</property>
                              <property name="icon_size">4</property>
@@ -294,7 +297,7 @@ Generally you cannot use this program in firewalled networks although try to ask
                          </child>
 
                          <child>
-                           <widget class="GtkLabel" id="label1">
+                           <widget class="GtkLabel" id="ButtonStartLabel">
                              <property name="visible">True</property>
                              <property name="label" translatable="yes">_Start</property>
                              <property name="use_underline">True</property>
@@ -326,9 +329,10 @@ Generally you cannot use this program in firewalled networks although try to ask
                  <property name="can_default">True</property>
                  <property name="can_focus">True</property>
                  <property name="relief">GTK_RELIEF_NORMAL</property>
+                 <signal name="clicked" handler="on_ButtonStop_clicked" last_modification_time="Sun, 09 May 2004 16:49:28 GMT"/>
 
                  <child>
-                   <widget class="GtkAlignment" id="alignment2">
+                   <widget class="GtkAlignment" id="ButtonStopAlignment">
                      <property name="visible">True</property>
                      <property name="xalign">0.5</property>
                      <property name="yalign">0.5</property>
@@ -336,13 +340,13 @@ Generally you cannot use this program in firewalled networks although try to ask
                      <property name="yscale">0</property>
 
                      <child>
-                       <widget class="GtkHBox" id="hbox2">
+                       <widget class="GtkHBox" id="ButtonStopHBox">
                          <property name="visible">True</property>
                          <property name="homogeneous">False</property>
                          <property name="spacing">2</property>
 
                          <child>
-                           <widget class="GtkImage" id="image2">
+                           <widget class="GtkImage" id="ButtonStopImage">
                              <property name="visible">True</property>
                              <property name="stock">gtk-stop</property>
                              <property name="icon_size">4</property>
@@ -359,7 +363,7 @@ Generally you cannot use this program in firewalled networks although try to ask
                          </child>
 
                          <child>
-                           <widget class="GtkLabel" id="label2">
+                           <widget class="GtkLabel" id="ButtonStopLabel">
                              <property name="visible">True</property>
                              <property name="label" translatable="yes">S_top</property>
                              <property name="use_underline">True</property>
@@ -391,9 +395,10 @@ Generally you cannot use this program in firewalled networks although try to ask
                  <property name="can_default">True</property>
                  <property name="can_focus">True</property>
                  <property name="relief">GTK_RELIEF_NORMAL</property>
+                 <signal name="clicked" handler="on_ButtonHide_clicked" last_modification_time="Sun, 09 May 2004 16:49:35 GMT"/>
 
                  <child>
-                   <widget class="GtkAlignment" id="alignment3">
+                   <widget class="GtkAlignment" id="ButtonHideAlignment">
                      <property name="visible">True</property>
                      <property name="xalign">0.5</property>
                      <property name="yalign">0.5</property>
@@ -401,13 +406,13 @@ Generally you cannot use this program in firewalled networks although try to ask
                      <property name="yscale">0</property>
 
                      <child>
-                       <widget class="GtkHBox" id="hbox3">
+                       <widget class="GtkHBox" id="ButtonHideHBox">
                          <property name="visible">True</property>
                          <property name="homogeneous">False</property>
                          <property name="spacing">2</property>
 
                          <child>
-                           <widget class="GtkImage" id="image3">
+                           <widget class="GtkImage" id="ButtonHideImage">
                              <property name="visible">True</property>
                              <property name="stock">gtk-apply</property>
                              <property name="icon_size">4</property>
@@ -424,7 +429,7 @@ Generally you cannot use this program in firewalled networks although try to ask
                          </child>
 
                          <child>
-                           <widget class="GtkLabel" id="label3">
+                           <widget class="GtkLabel" id="ButtonHideLabel">
                              <property name="visible">True</property>
                              <property name="label" translatable="yes">_Hide</property>
                              <property name="use_underline">True</property>
index f7f2fe9..bc40bd5 100644 (file)
@@ -26,7 +26,8 @@
 
 G_BEGIN_DECLS
 
-void ui_gnome_init(void);
+gboolean ui_gnome_init(void);
+void ui_gnome_interactive(void);
 
 G_END_DECLS