Cosmetic: Fixed warn.
[udpgate.git] / src / main.c
index e69de29..c80685b 100644 (file)
@@ -0,0 +1,333 @@
+/* $Id$
+ * UDP Gateway utility
+ * 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
+ * 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>
+
+#ifdef HAVE_GNOME
+#include <libgnome/gnome-program.h>
+#include <libgnomeui/gnome-ui-init.h>
+#endif
+
+#include "main.h"      /* self */
+#include "ui-line.h"
+#include "network.h"
+#include "configuration.h"
+#include "static-startup.h"
+#ifdef ENABLE_BUNDLE
+#include "bundle-util.h"
+#endif
+
+#ifdef HAVE_GNOME
+#include "ui-gnome.h"
+#endif
+
+
+/* Config: */
+#define LOCAL_PORT_DEFAULT 9201
+
+
+static int optarg_text;
+int optarg_verbose;
+int optarg_port=LOCAL_PORT_DEFAULT;
+static int optarg_start;
+static int optarg_stop;
+int optarg_no_fork;
+static int optarg_startup_query;
+static int optarg_startup_on;
+static int optarg_startup_off;
+
+void (*ui_interactive)(void);
+
+static const struct poptOption popt_table[]={
+
+#define UDPGATE_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), \
+               }
+
+#ifdef HAVE_GNOME
+#define OPT_TEXT_IF_GNOME N_("Disable Gnome UI; --text must be first argument")
+#else /* HAVE_GNOME */
+#define OPT_TEXT_IF_GNOME N_("(no Gnome UI compiled - stub only); --text must be first argument")
+#endif /* HAVE_GNOME */
+               UDPGATE_POPT(0  ,"text"         ,POPT_ARG_NONE                          ,&optarg_text         ,0,
+                               OPT_TEXT_IF_GNOME,NULL),                                                                  
+#undef OPT_TEXT_IF_GNOME                                                                          
+               UDPGATE_POPT('v',"verbose"      ,POPT_ARG_NONE                          ,&optarg_verbose      ,0,
+                               N_("Display additional debug information"),NULL),                                         
+               UDPGATE_POPT('p',"port"         ,POPT_ARG_INT |POPT_ARGFLAG_SHOW_DEFAULT,&optarg_port         ,0,
+                               N_("Listen on this UDP port"),NULL),                                                      
+               UDPGATE_POPT('s',"start"        ,POPT_ARG_NONE                          ,&optarg_start        ,0,
+                               N_("Start the daemon"),NULL),                                                             
+               UDPGATE_POPT('S',"stop"         ,POPT_ARG_NONE                          ,&optarg_stop         ,0,
+                               N_("Stop the daemon"),NULL),
+               UDPGATE_POPT('1',"no-fork"      ,POPT_ARG_NONE                          ,&optarg_no_fork      ,0,
+                               N_("Do not detach from the current process"),NULL),
+               UDPGATE_POPT(0  ,"startup-query",POPT_ARG_NONE                          ,&optarg_startup_query,0,
+                               N_("Query the current state of the system startup registrance"),NULL),
+               UDPGATE_POPT(0  ,"startup-on"   ,POPT_ARG_NONE                          ,&optarg_startup_on   ,0,
+                               N_("Register for the automatic system startup"),NULL),
+               UDPGATE_POPT(0  ,"startup-off"  ,POPT_ARG_NONE                          ,&optarg_startup_off  ,0,
+                               N_("Unregister from the automatic system startup"),NULL),
+
+#undef UDPGATE_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
+               };
+
+
+#ifdef HAVE_GNOME
+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);
+}
+
+static 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);
+}
+#endif /* HAVE_GNOME */
+
+static gchar *localedir;
+
+#ifdef ENABLE_BUNDLE
+static gboolean locale_files_write(void)
+{
+gchar catalogs[]=G_STRINGIFY(CATALOGS);
+gchar *catalog,*catalog_next;
+
+       for (catalog=catalogs;*catalog;catalog=catalog_next) {
+gchar *cc,*cc_end;
+
+               for (catalog_next=catalog;*catalog_next && *catalog_next!=' ';catalog_next++);
+               if (*catalog_next)
+                       *catalog_next++='\0';
+               cc=g_strdup(catalog);
+               cc_end=cc+strlen(cc)-strlen(".gmo");
+               if (cc_end>cc && !strcmp(cc_end,".gmo")) {
+                       *cc_end='\0';
+                       if (!bundle_util_file_write(
+                                       udpgate_printf_alloca("%s/%s/LC_MESSAGES/%s.mo",LOCALEDIR,cc,PACKAGE),  /* pathname */
+                                       catalog,        /* basename */
+                                       0644,   /* pathname_mode */
+                                       BUNDLE_UTIL_MKDIRS_MASK|BUNDLE_UTIL_TEMPORARY_MASK)) {  /* flags */
+const gchar *tmpdir=g_get_tmp_dir();
+const gchar *username=g_get_user_name();
+gchar *trylocaledir=localedir;
+
+                               if (!trylocaledir && tmpdir && username)
+                                       trylocaledir=g_strdup_printf("%s/.%s-%s/locale",tmpdir,username,PACKAGE);
+                               if (trylocaledir && bundle_util_file_write(
+                                               udpgate_printf_alloca("%s/%s/LC_MESSAGES/%s.mo",trylocaledir,cc,PACKAGE),       /* pathname */
+                                               catalog,        /* basename */
+                                               0644,   /* pathname_mode */
+                                               BUNDLE_UTIL_MKDIRS_MASK|BUNDLE_UTIL_TEMPORARY_MASK))    /* flags */
+                                       localedir=trylocaledir;
+                               }
+
+                       }
+               g_free(cc);
+               }
+       return FALSE;
+}
+#endif /* ENABLE_BUNDLE */
+
+int main(int argc,char **argv)
+{
+poptContext context;
+int errint;
+gboolean is_interactive;
+#ifdef HAVE_GNOME
+gboolean no_gnome;
+#endif /* HAVE_GNOME */
+int exit_rc=EXIT_SUCCESS;
+
+#ifdef ENABLE_BUNDLE
+       locale_files_write();
+#endif /* ENABLE_BUNDLE */
+
+#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,"");
+       if (!localedir)
+               localedir=LOCALEDIR;
+       bindtextdomain(PACKAGE,localedir);
+       textdomain(PACKAGE);
+
+       /* Read it before the command-line parsing to get the default value
+        * of 'optarg_port' displayable by 'POPT_ARGFLAG_SHOW_DEFAULT'.
+        */
+       configuration_read();
+
+       if (argv[1] && !strcmp(argv[1],"--text"))
+               optarg_text=1;
+
+#ifdef HAVE_GNOME
+       no_gnome=(optarg_text || !getenv("DISPLAY") || !*getenv("DISPLAY"));
+
+       if (no_gnome)
+#endif /* HAVE_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_error(_("Specified option not expected"));
+               if (poptPeekArg(context))
+                       g_error(_("No arguments expected"));
+               }
+#ifdef HAVE_GNOME
+       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: (udpgate: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 */
+               }
+#endif /* HAVE_GNOME */
+
+       configuration_write();
+
+       is_interactive=(1
+                       && !optarg_start
+                       && !optarg_stop
+                       && !optarg_startup_query
+                       && !optarg_startup_on
+                       && !optarg_startup_off);
+
+       /* Initialize UI here to catch all GLog errors below. */
+       if (is_interactive
+#ifdef HAVE_GNOME
+                       && (no_gnome || !ui_gnome_init())
+#endif /* HAVE_GNOME */
+                       && !ui_line_init())
+               g_error(_("No UI interface could be initialized"));
+
+       if (!is_interactive) {
+
+               if (optarg_stop)
+                       if (!network_stop())
+                               exit_rc=2;
+               if (optarg_startup_query) {
+gboolean is_on;
+
+                       if (static_startup_query(&is_on)) {
+                               g_message((is_on
+                                               ? _("System startup registrance is turned on.")
+                                               : _("System startup registrance is turned off.")));
+                               if (exit_rc<2)
+                                       exit_rc=(is_on ? 0 : 1);
+                               }
+                       else
+                               exit_rc=2;
+                       }
+               if (optarg_startup_off) {
+                       if (!static_startup_off())
+                               exit_rc=2;
+                       }
+               if (optarg_startup_on) {
+                       if (!static_startup_on())
+                               exit_rc=2;
+                       }
+               if (optarg_start)
+                       if (!network_start(optarg_port))
+                               exit_rc=2;
+
+               network_detach();
+               }
+       else
+               (*ui_interactive)();
+
+       configuration_write();
+
+       exit(exit_rc);
+}