00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #define GNU_PREFIX ""
00025
00026 #ifdef HAVE_CONFIG_H
00027 # include <config.h>
00028 #endif
00029
00030 #ifdef HAVE_UNISTD_H
00031 # include <unistd.h>
00032 #else
00033 # ifdef HAVE_SYS_UNISTD_H
00034 # include <sys/unistd.h>
00035 # endif
00036 #endif
00037
00038 #ifdef HAVE_LOCALE_H
00039 # include <locale.h>
00040 #endif
00041
00042 #ifdef HAVE_SYSLOG_H
00043 # include <syslog.h>
00044 #else
00045 # define syslog(FOO)
00046 #endif
00047
00048 #ifdef HAVE_TYPES_H
00049 # include <types.h>
00050 #else
00051 # ifdef HAVE_SYS_TYPES_H
00052 # include <sys/types.h>
00053 # endif
00054 #endif
00055
00056 #ifdef HAVE_STRING_H
00057 # include <string.h>
00058 #else
00059 # ifdef HAVE_STRINGS_H
00060 # include <strings.h>
00061 # endif
00062 #endif
00063
00064 #include <pwd.h>
00065 #include <errno.h>
00066 #include <signal.h>
00067 #include <stdio.h>
00068 #include <stdlib.h>
00069 #include <sys/stat.h>
00070
00071 #ifdef HAVE_GETOPT_LONG
00072 # include <getopt.h>
00073 #endif
00074
00075 #ifdef HAVE_SOCKET_H
00076 # include <socket.h>
00077 #else
00078 # ifdef HAVE_SYS_SOCKET_H
00079 # include <sys/socket.h>
00080 # endif
00081 #endif
00082
00083 #include "common/socket.h"
00084
00085 #include "renderers/charrenderer.h"
00086 #include "renderers/charcanvas.h"
00087
00088 #include "connections.h"
00089 #include "drivers.h"
00090 #include "xmlconfig.h"
00091
00092
00093 #if ENABLE_NLS
00094 # include <libintl.h>
00095 # define _(foo) gettext (foo)
00096 #else
00097 # define bindtextdomain(X,Y)
00098 # define textdomain(Domain)
00099 # define _(foo) foo
00100 #endif
00101
00102 #ifdef HAVE_GETOPT_LONG
00103
00104 static struct option longopts[] = {
00105 {"port", required_argument, 0, 'p'},
00106 #ifdef HAVE_FORK
00107 {"foreground", no_argument, 0, 'f'},
00108 #endif
00109 {"help", no_argument, 0, 'h'},
00110 {"version", no_argument, 0, 'V'},
00111 {0, 0, 0, 0}
00112 };
00113 #endif
00114
00115
00116
00117
00118 void
00119 sighup_handler ()
00120 {
00121 syslog (LOG_INFO, _("received SIGHUP"));
00122 }
00123
00124
00125 void
00126 sigterm_handler ()
00127 {
00128 syslog (LOG_INFO, _("received SIGTERM, exiting"));
00129 exit (EXIT_SUCCESS);
00130 }
00131
00132
00133 void
00134 exit_program ()
00135 {
00136 syslog (LOG_INFO, _("exiting"));
00137 closelog ();
00138 exit (EXIT_FAILURE);
00139 }
00140
00141
00142 void
00143 sys_err (const char *errstr)
00144 {
00145 syslog (LOG_ERR, errstr);
00146 exit_program ();
00147 }
00148
00149
00150 void
00151 show_help (const char *app_name)
00152 {
00153 printf (_("Usage: %s [options] ...\nOptions:\n"), app_name);
00154 #ifdef HAVE_GETOPT_LONG
00155 printf (_(" \
00156 --port, -p <portnr> Let the server listen on another port number\n"));
00157 printf (_(" --foreground, -f Run the server in the foreground\n"));
00158 printf (_(" --help, -h Program usage\n"));
00159 printf (_(" --version, -V Show program version and exit\n"));
00160 #else
00161 printf (_(" -p <portnr> Let the server listen on another port number\n"));
00162 printf (_(" -b Run the server in the foreground\n"));
00163 printf (_(" -h Program usage\n"));
00164 printf (_(" -V Show program version and exit\n"));
00165 #endif
00166 printf (_("\nReport bugs to <%s>\n"), PACKAGE_BUGREPORT);
00167 }
00168
00169
00170 void
00171 show_version (const char *app_name)
00172 {
00173 printf ("%s - %s%s\n", app_name, GNU_PREFIX, PACKAGE_STRING);
00174 printf (_("Copyright (C) %s %s\n"), "2002, 2003", "Jeroen van den Berg");
00175 printf (_("\
00176 This program is free software; you may redistribute it under the terms of\n\
00177 the GNU General Public License. This program comes with absolutely NO\n\
00178 WARRANTY. For more information about these matters, see the file named\n\
00179 COPYING.\n"));
00180 }
00181
00182
00183 void
00184 drop_root_privilege (const char *user)
00185 {
00186 struct passwd *pw_ent;
00187
00188
00189
00190
00191
00192 if (getuid () == 0 || geteuid () == 0)
00193 {
00194 pw_ent = getpwnam (user);
00195 if (! pw_ent)
00196 {
00197 syslog (LOG_WARNING,
00198 _("user %s is not a valid user, fallback to 'nobody'\n"),
00199 user);
00200 pw_ent = getpwnam ("nobody");
00201 if (! pw_ent)
00202 {
00203 sys_err (_("cannot drop root privileges, aborting"));
00204 exit (EXIT_FAILURE);
00205 }
00206 }
00207
00208 if (setuid (pw_ent->pw_uid) < 0)
00209 sys_err ("setuid");
00210 }
00211 }
00212
00213
00214
00215 int
00216 main (int argc, char **argv)
00217 {
00218 char c;
00219 int run_in_foreground = 0;
00220 unsigned int port = 8800;
00221 const char *app_name;
00222 pid_t child;
00223 long tmp;
00224 socket_t sock;
00225 fd_set fdset;
00226 xml_node *xconf;
00227 xml_node *output_config;
00228 void *driver;
00229 xml_node *fooxy;
00230 cl_layout *foox;
00231 cc_canvas *canvas;
00232 unsigned int i;
00233
00234
00235 setlocale (LC_ALL, "");
00236 bindtextdomain (PACKAGE, "/usr/share/locale");
00237 textdomain (PACKAGE);
00238
00239
00240 app_name = *argv + strlen (*argv) - 1;
00241 while (app_name > *argv && *(app_name - 1) != '/')
00242 --app_name;
00243
00244
00245 #ifdef HAVE_GETOPT_LONG
00246 while ((c = getopt_long (argc, argv, "p:bhV", longopts, 0)) > 0)
00247 #else
00248 while ((c = getopt (argc, argv, "p:bhV")) > 0)
00249 #endif
00250 {
00251 switch (c)
00252 {
00253 case 'p':
00254 tmp = strtol (optarg, 0, 10);
00255 if (errno == ERANGE || tmp < 1 || tmp > 65536)
00256 {
00257 fprintf (stderr,
00258 _("Port number must be between 1 and 65536\n"));
00259 exit (EXIT_FAILURE);
00260 }
00261 port = tmp;
00262 break;
00263
00264 case 'f':
00265 run_in_foreground = 1;
00266 break;
00267
00268 case 'h':
00269 show_help (app_name);
00270 exit (EXIT_SUCCESS);
00271 break;
00272
00273 case 'V':
00274 show_version (app_name);
00275 exit (EXIT_SUCCESS);
00276 break;
00277
00278 case '?':
00279 show_help (app_name);
00280 exit (EXIT_FAILURE);
00281 break;
00282
00283 default:
00284
00285 exit (EXIT_FAILURE);
00286 }
00287 }
00288
00289 if (optind < argc)
00290 {
00291 perror (_("too many arguments"));
00292 exit (EXIT_FAILURE);
00293 }
00294
00295
00296 #ifdef HAVE_FORK
00297 if (!run_in_foreground)
00298 {
00299 child = fork();
00300 if( child < 0 )
00301 sys_err( "fork" );
00302
00303 if( child != 0 )
00304 exit( EXIT_SUCCESS );
00305
00306
00307 if( setsid() < 0 )
00308 sys_err( "setsid" );
00309 }
00310 #endif
00311
00312
00313 openlog (app_name, LOG_CONS | LOG_PID | LOG_PERROR, LOG_DAEMON);
00314
00315
00316
00317
00318
00319
00320 umask (0);
00321 if (!run_in_foreground)
00322 {
00323 close( STDOUT_FILENO );
00324 close( STDERR_FILENO );
00325 }
00326 close( STDIN_FILENO );
00327
00328
00329 sock = socket_create_server (port, &fdset);
00330 if (sock < 0)
00331 {
00332 switch (sock)
00333 {
00334 case -1:
00335 sys_err ("socket()");
00336 break;
00337 case -2:
00338 sys_err ("setsockopt()");
00339 break;
00340 case -3:
00341 sys_err ("bind()");
00342 break;
00343 case -4:
00344 sys_err ("listen()");
00345 break;
00346 default:
00347 sys_err (_("cannot open server socket"));
00348 break;
00349 }
00350 exit (EXIT_FAILURE);
00351 }
00352
00353
00354
00355
00356 drop_root_privilege (app_name);
00357
00358
00359 xconf = xc_parse_config_file ("flcdd.xml");
00360 if (! xconf)
00361 {
00362 sys_err (_("Failed to parse inifile"));
00363 exit (EXIT_FAILURE);
00364 }
00365
00366
00367 fooxy = xc_parse_config_file ("../renderers/testlayout.xml");
00368 foox = cl_make_layout (fooxy);
00369
00370 canvas = cc_create_canvas (20, 4);
00371 for (i = 0; i < foox->layout_data_size; ++i)
00372 {
00373 unsigned int x = foox->layout_data[i].x;
00374 unsigned int y = foox->layout_data[i].y;
00375 unsigned int j;
00376
00377 for (j = 0; j < foox->layout_data[i].width; ++j)
00378 cc_put_char (canvas, x + j, y, foox->layout_data[i].utf8_data[j]);
00379 }
00380
00381
00382 drivers_init ();
00383 output_config = 0;
00384 while ((output_config = xmlt_find (xconf, output_config, OUTPUT)) != 0)
00385 {
00386 const char* output_id_s = xmlt_get_attrib (output_config, ID);
00387 int output_id = 1;
00388
00389 if (output_id_s)
00390 output_id = atoi (output_id_s);
00391
00392 driver = drivers_create_output (output_config);
00393
00394 if (!driver)
00395 puts ("drivers_create_output failed");
00396 }
00397
00398 drivers_process_canvas (driver, canvas);
00399 xmlt_free_document (xconf);
00400
00401 signal (SIGHUP, sighup_handler);
00402 signal (SIGTERM, sigterm_handler);
00403
00404
00405
00406 while (1)
00407 {
00408
00409
00410
00411
00412 socket_poll (sock, &fdset, conn_open, conn_data, conn_close);
00413 }
00414
00415 closelog ();
00416 return EXIT_SUCCESS;
00417 }