/etc/sysconfig/udpgate configuration file read/write support.
[udpgate.git] / src / main.c
1 /* $Id$
2  * UDP Gateway utility
3  * Copyright (C) 2004 Jan Kratochvil <project-udpgate@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 <glib/gmessages.h>
23 #include <popt.h>
24 #include <locale.h>
25 #include <stdlib.h>
26 #include <glib/gutils.h>
27 #include <string.h>
28 #include <setjmp.h>
29 #include <unistd.h>
30
31 #ifdef HAVE_GNOME
32 #include <libgnome/gnome-program.h>
33 #include <libgnomeui/gnome-ui-init.h>
34 #endif
35
36 #include "main.h"       /* self */
37 #include "ui-line.h"
38 #include "network.h"
39 #include "configuration.h"
40
41 #ifdef HAVE_GNOME
42 #include "ui-gnome.h"
43 #endif
44
45
46 /* Config: */
47 #define LOCAL_PORT_DEFAULT 9201
48
49
50 static int optarg_text;
51 int optarg_verbose;
52 int optarg_port=LOCAL_PORT_DEFAULT;
53 static int optarg_start;
54 static int optarg_stop;
55 int optarg_no_fork;
56
57 void (*ui_interactive)(void);
58
59 static const struct poptOption popt_table[]={
60
61 #define UDPGATE_POPT(shortname,longname,argInfoP,argP,valP,descripP,argDescripP) \
62                 { \
63                         longName: (longname), \
64                         shortName: (shortname), \
65                         argInfo: (argInfoP)|(!(valP) ? 0 : POPT_ARG_VAL), \
66                         arg: (void *)argP, \
67                         val: (valP), \
68                         descrip: (descripP), \
69                         argDescrip: (argDescripP), \
70                 }
71
72 #ifdef HAVE_GNOME
73 #define OPT_TEXT_IF_GNOME N_("Disable Gnome UI; --text must be first argument")
74 #else /* HAVE_GNOME */
75 #define OPT_TEXT_IF_GNOME N_("(no Gnome UI compiled - stub only); --text must be first argument")
76 #endif /* HAVE_GNOME */
77                 UDPGATE_POPT(0  ,"text"   ,POPT_ARG_NONE                          ,&optarg_text   ,0,
78                                 OPT_TEXT_IF_GNOME,NULL),
79 #undef OPT_TEXT_IF_GNOME
80                 UDPGATE_POPT('v',"verbose",POPT_ARG_NONE                          ,&optarg_verbose,0,
81                                 N_("Display additional debug information"),NULL),
82                 UDPGATE_POPT('p',"port"   ,POPT_ARG_INT |POPT_ARGFLAG_SHOW_DEFAULT,&optarg_port   ,0,
83                                 N_("Listen on this UDP port"),NULL),
84                 UDPGATE_POPT('s',"start"  ,POPT_ARG_NONE                          ,&optarg_start  ,0,
85                                 N_("Start the daemon"),NULL),
86                 UDPGATE_POPT('S',"stop"   ,POPT_ARG_NONE                          ,&optarg_stop   ,0,
87                                 N_("Stop the daemon"),NULL),
88                 UDPGATE_POPT('1',"no-fork",POPT_ARG_NONE                          ,&optarg_no_fork,0,
89                                 N_("Do not detach from the current process"),NULL),
90
91 #undef UDPGATE_POPT
92                 POPT_TABLEEND
93                 };
94
95 static const struct poptOption popt_table_autohelp[]={
96                 { NULL,'\0',POPT_ARG_INCLUDE_TABLE,(struct poptOption *)&popt_table,0,PACKAGE },
97                 POPT_AUTOHELP
98                 POPT_TABLEEND
99                 };
100
101
102 #ifdef HAVE_GNOME
103 static jmp_buf gnome_init_atexit_jmpbuf;
104 static gboolean gnome_init_atexit_disable;
105
106 static void gnome_init_atexit_handler(void)
107 {
108         if (gnome_init_atexit_disable)
109                 return;
110
111         longjmp(gnome_init_atexit_jmpbuf,1);
112         g_assert_not_reached();
113         _exit(EXIT_FAILURE);
114 }
115
116 static gboolean gnome_init_g_log_handler_hit;
117 static void gnome_init_g_log_handler(const gchar *log_domain,GLogLevelFlags log_level,const gchar *message,gpointer user_data)
118 {
119         gnome_init_g_log_handler_hit=TRUE;
120         g_log_default_handler(log_domain,log_level,message,user_data);
121 }
122 #endif /* HAVE_GNOME */
123
124 int main(int argc,char **argv)
125 {
126 poptContext context;
127 int errint;
128 gboolean is_interactive;
129 #ifdef HAVE_GNOME
130 gboolean no_gnome;
131 #endif /* HAVE_GNOME */
132
133 #if 0
134         g_log_set_always_fatal(~(0
135                         |G_LOG_LEVEL_MESSAGE
136                         |G_LOG_LEVEL_INFO
137                         |G_LOG_LEVEL_DEBUG
138                         ));
139 #endif
140
141         /* Initialize the i18n stuff */
142         setlocale(LC_ALL,"");
143         bindtextdomain(PACKAGE,LOCALEDIR);
144         textdomain(PACKAGE);
145
146         /* Read it before the command-line parsing to get the default value
147          * of 'optarg_port' displayable by 'POPT_ARGFLAG_SHOW_DEFAULT'.
148          */
149         configuration_read();
150
151         if (argv[1] && !strcmp(argv[1],"--text"))
152                 optarg_text=1;
153
154 #ifdef HAVE_GNOME
155         no_gnome=(optarg_text || !getenv("DISPLAY") || !*getenv("DISPLAY"));
156
157         if (no_gnome)
158 #endif /* HAVE_GNOME */
159         {
160                 context=poptGetContext(
161                                 PACKAGE,        /* name */
162                                 argc,(/*en-const*/const char **)argv,   /* argc,argv */
163                                 popt_table_autohelp,    /* options */
164                                 POPT_CONTEXT_POSIXMEHARDER);    /* flags; && !POPT_CONTEXT_KEEP_FIRST */
165                 if (context==NULL) {
166                         g_assert_not_reached(); /* argument recognization args_error */
167                         return EXIT_FAILURE;
168                         }
169                 errint=poptReadDefaultConfig(context,
170                                 TRUE);  /* useEnv */
171                 if (errint!=0) {
172                         g_assert_not_reached(); /* argument recognization args_error */
173                         return EXIT_FAILURE;
174                         }
175                 errint=poptGetNextOpt(context);
176                 if (errint!=-1)
177                         g_error(_("Specified option not expected"));
178                 if (poptPeekArg(context))
179                         g_error(_("No arguments expected"));
180                 }
181 #ifdef HAVE_GNOME
182         else {
183 GnomeProgram *gnome_program;
184 guint handler_id;
185
186                 gnome_init_atexit_disable=FALSE;
187                 g_atexit(gnome_init_atexit_handler);
188                 gnome_init_g_log_handler_hit=FALSE;
189                 handler_id=g_log_set_handler(
190                                 "Gtk",  /* log_domain */
191                                 G_LOG_LEVEL_WARNING,    /* log_levels */
192                                 gnome_init_g_log_handler,       /* log_func */
193                                 NULL);  /* user_data */
194                 if (!setjmp(gnome_init_atexit_jmpbuf))
195                         gnome_program=gnome_program_init(PACKAGE,VERSION,LIBGNOMEUI_MODULE,argc,argv,
196                                         GNOME_PARAM_POPT_TABLE,popt_table,
197                                         GNOME_PARAM_POPT_FLAGS,(int)POPT_CONTEXT_POSIXMEHARDER,
198                                         NULL);
199                 else {
200                         no_gnome=TRUE;
201                         /* No message: (udpgate:3693): Gtk-WARNING **: cannot open display:
202                          * was reported, probably only '--help' message was shown.
203                          */
204                         if (!gnome_init_g_log_handler_hit)
205                                 exit(EXIT_SUCCESS);
206                         }
207                 gnome_init_atexit_disable=TRUE;
208                 g_log_remove_handler(
209                                 "Gtk",  /* log_domain */
210                                 handler_id);    /* handler_id */
211                 }
212 #endif /* HAVE_GNOME */
213
214         is_interactive=(1
215                         && !optarg_start
216                         && !optarg_stop);
217
218         /* Initialize UI here to catch all GLog errors below. */
219         if (is_interactive
220 #ifdef HAVE_GNOME
221                         && (no_gnome || !ui_gnome_init())
222 #endif /* HAVE_GNOME */
223                         && !ui_line_init())
224                 g_error(_("No UI interface could be initialized"));
225
226         if (!is_interactive) {
227                 if (optarg_stop)
228                         network_stop();
229                 if (optarg_start)
230                         network_start(optarg_port);
231                 network_detach();
232                 }
233         else
234                 (*ui_interactive)();
235
236         configuration_write();
237
238         return EXIT_SUCCESS;
239 }