- Modified forking. Child will now signal parent when it has started up OK. Only after that (or error) parent dies.
- Modified startup order of LCDd parts. - Moved code for starting up the socket from main.c to sock.c - Variable daemon_mode renamed to foreground_mode, consistent with command line. - Variable lcd_port renamed to bind_port. - Modified the constant stay_in_foreground for drivers hd44780 and sed1330. They don't need to stay in foreground anymore.
This commit is contained in:
@@ -111,7 +111,7 @@ static int parse_span_list (int *spanListArray[], int *spLsize, int *dispOffsets
|
|||||||
|
|
||||||
// Vars for the server core
|
// Vars for the server core
|
||||||
MODULE_EXPORT char * api_version = API_VERSION;
|
MODULE_EXPORT char * api_version = API_VERSION;
|
||||||
MODULE_EXPORT int stay_in_foreground = 1; // because of port access problems
|
MODULE_EXPORT int stay_in_foreground = 0;
|
||||||
MODULE_EXPORT int supports_multiple = 1; // yes, we have no global variables (except for constants)
|
MODULE_EXPORT int supports_multiple = 1; // yes, we have no global variables (except for constants)
|
||||||
MODULE_EXPORT char *symbol_prefix = "HD44780_";
|
MODULE_EXPORT char *symbol_prefix = "HD44780_";
|
||||||
|
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ static char *defaultKeyMapMatrix[KEYPAD_MAXY][KEYPAD_MAXX] = {
|
|||||||
|
|
||||||
// Vars for the server core
|
// Vars for the server core
|
||||||
MODULE_EXPORT char * api_version = API_VERSION;
|
MODULE_EXPORT char * api_version = API_VERSION;
|
||||||
MODULE_EXPORT int stay_in_foreground = 1;
|
MODULE_EXPORT int stay_in_foreground = 0;
|
||||||
MODULE_EXPORT int supports_multiple = 1; // yes, we have no global variables (except for constants)
|
MODULE_EXPORT int supports_multiple = 1; // yes, we have no global variables (except for constants)
|
||||||
MODULE_EXPORT char *symbol_prefix = "sed1330_";
|
MODULE_EXPORT char *symbol_prefix = "sed1330_";
|
||||||
|
|
||||||
|
|||||||
+143
-75
@@ -37,6 +37,8 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
@@ -69,7 +71,7 @@ extern int optind, optopt, opterr;
|
|||||||
#define DEFAULT_DRIVER "curses"
|
#define DEFAULT_DRIVER "curses"
|
||||||
#define DEFAULT_DRIVER_PATH
|
#define DEFAULT_DRIVER_PATH
|
||||||
#define MAX_DRIVERS 8
|
#define MAX_DRIVERS 8
|
||||||
#define DEFAULT_DAEMON_MODE 1
|
#define DEFAULT_FOREGROUND_MODE 0
|
||||||
#define DEFAULT_ROTATE_SERVER_SCREEN 1
|
#define DEFAULT_ROTATE_SERVER_SCREEN 1
|
||||||
#define DEFAULT_REPORTTOSYSLOG 0
|
#define DEFAULT_REPORTTOSYSLOG 0
|
||||||
#define DEFAULT_REPORTLEVEL RPT_WARNING
|
#define DEFAULT_REPORTLEVEL RPT_WARNING
|
||||||
@@ -97,21 +99,19 @@ char *build_date = __DATE__;
|
|||||||
/* Some variables are settable on the command line. This are variables that
|
/* Some variables are settable on the command line. This are variables that
|
||||||
* change the mode of operation. This includes settings that you can use to
|
* change the mode of operation. This includes settings that you can use to
|
||||||
* enable debugging: driver selection, report settings, bind address etc.
|
* enable debugging: driver selection, report settings, bind address etc.
|
||||||
|
* These variables should be in main.h and main.c (below).
|
||||||
|
*
|
||||||
* All other settings do not need to be settable from the command line. They
|
* All other settings do not need to be settable from the command line. They
|
||||||
* also do not necesarily need to be read in main.c but can better be read in
|
* also do not necesarily need to be read in main.c but can better be read in
|
||||||
* in the file concerned.
|
* in the file concerned.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* All variables are set to 'unset' values*/
|
unsigned int bind_port = UNSET_INT;
|
||||||
#define UNSET_INT -1
|
|
||||||
#define UNSET_STR "\01"
|
|
||||||
|
|
||||||
int lcd_port = UNSET_INT;
|
|
||||||
char bind_addr[64]; /* Do not preinit these strings as they will occupy */
|
char bind_addr[64]; /* Do not preinit these strings as they will occupy */
|
||||||
char configfile[256]; /* a lot of space in the executable. */
|
char configfile[256]; /* a lot of space in the executable. */
|
||||||
char user[64]; /* The values will be overwritten anyway... */
|
char user[64]; /* The values will be overwritten anyway... */
|
||||||
|
|
||||||
int daemon_mode = UNSET_INT;
|
int foreground_mode = UNSET_INT;
|
||||||
|
|
||||||
static int report_level = UNSET_INT;
|
static int report_level = UNSET_INT;
|
||||||
static int report_to_syslog = UNSET_INT;
|
static int report_to_syslog = UNSET_INT;
|
||||||
@@ -119,10 +119,15 @@ static int report_to_syslog = UNSET_INT;
|
|||||||
/* The drivers and their driver parameters */
|
/* The drivers and their driver parameters */
|
||||||
char *drivernames[MAX_DRIVERS];
|
char *drivernames[MAX_DRIVERS];
|
||||||
int num_drivers = 0;
|
int num_drivers = 0;
|
||||||
|
|
||||||
|
/* End of configuration variables */
|
||||||
|
|
||||||
|
/* Local variables */
|
||||||
int stored_argc;
|
int stored_argc;
|
||||||
char **stored_argv;
|
char **stored_argv;
|
||||||
short got_reload_signal = 0;
|
short got_reload_signal = 0;
|
||||||
|
|
||||||
|
/* Local exported variables */
|
||||||
long int timer = 0;
|
long int timer = 0;
|
||||||
|
|
||||||
/**** Local functions ****/
|
/**** Local functions ****/
|
||||||
@@ -130,8 +135,10 @@ void clear_settings();
|
|||||||
int process_command_line (int argc, char **argv);
|
int process_command_line (int argc, char **argv);
|
||||||
int process_configfile (char *cfgfile);
|
int process_configfile (char *cfgfile);
|
||||||
void set_default_settings();
|
void set_default_settings();
|
||||||
int daemonize();
|
void install_signal_handlers (int allow_reload);
|
||||||
int init_sockets();
|
void child_ok_func (int signal);
|
||||||
|
pid_t daemonize();
|
||||||
|
int wave_to_parent (pid_t parent_pid);
|
||||||
int init_drivers();
|
int init_drivers();
|
||||||
int drop_privs(char *user);
|
int drop_privs(char *user);
|
||||||
int init_screens();
|
int init_screens();
|
||||||
@@ -150,17 +157,11 @@ int
|
|||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int e = 0;
|
int e = 0;
|
||||||
|
pid_t parent_pid = 0;
|
||||||
|
|
||||||
stored_argc = argc;
|
stored_argc = argc;
|
||||||
stored_argv = argv;
|
stored_argv = argv;
|
||||||
|
|
||||||
signal (SIGINT, exit_program); /* Ctrl-C will cause a clean exit...*/
|
|
||||||
signal (SIGTERM, exit_program); /* and "kill"...*/
|
|
||||||
signal (SIGKILL, exit_program); /* and just in case, "kill -KILL" (which cannot be trapped; but oh well)*/
|
|
||||||
|
|
||||||
signal (SIGHUP, catch_reload_signal); /* On SIGHUP reread config and restart the drivers ! */
|
|
||||||
/* Let's see if we can actually get this to work ;) */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Settings in order of preference:
|
* Settings in order of preference:
|
||||||
*
|
*
|
||||||
@@ -205,27 +206,35 @@ main (int argc, char **argv)
|
|||||||
report( RPT_INFO, "Set report level to %d, output to %s", report_level, (report_to_syslog?"syslog":"stderr") );
|
report( RPT_INFO, "Set report level to %d, output to %s", report_level, (report_to_syslog?"syslog":"stderr") );
|
||||||
CHAIN_END( e, "Critical error while processing settings, abort." );
|
CHAIN_END( e, "Critical error while processing settings, abort." );
|
||||||
|
|
||||||
/* Startup the server*/
|
/* Now, go into daemon mode (if we should)...
|
||||||
CHAIN( e, screenlist_init() );
|
* We wait for the child to report it is running OK. This mechanism
|
||||||
CHAIN( e, init_drivers() );
|
* is used because forking after starting the drivers causes the
|
||||||
CHAIN( e, init_sockets() );
|
* child to loose the (LPT) port access. */
|
||||||
CHAIN( e, input_init() );
|
if (!foreground_mode) {
|
||||||
CHAIN( e, menuscreens_init() );
|
|
||||||
CHAIN( e, server_screen_init() );
|
|
||||||
CHAIN( e, drop_privs(user) );
|
|
||||||
CHAIN_END( e, "Critical error while initializing, abort." );
|
|
||||||
|
|
||||||
/* Now, go into daemon mode...*/
|
|
||||||
/* TODO: do this earlier and let parent process wait until
|
|
||||||
* child has fully started or reported its errors. */
|
|
||||||
if (daemon_mode) {
|
|
||||||
report(RPT_INFO, "Server forking to background");
|
report(RPT_INFO, "Server forking to background");
|
||||||
CHAIN( e, daemonize() );
|
CHAIN( e, parent_pid = daemonize() );
|
||||||
} else {
|
} else {
|
||||||
output_GPL_notice();
|
output_GPL_notice();
|
||||||
report(RPT_INFO, "Server running in foreground");
|
report(RPT_INFO, "Server running in foreground");
|
||||||
}
|
}
|
||||||
|
install_signal_handlers (!foreground_mode);
|
||||||
|
/* Only catch SIGHUP if not in foreground mode */
|
||||||
|
|
||||||
|
/* Startup the subparts of the server */
|
||||||
|
CHAIN( e, sock_init() );
|
||||||
|
CHAIN( e, screenlist_init() );
|
||||||
|
CHAIN( e, init_drivers() );
|
||||||
|
CHAIN( e, clients_init() );
|
||||||
|
CHAIN( e, input_init() );
|
||||||
|
CHAIN( e, menuscreens_init() );
|
||||||
|
CHAIN( e, server_screen_init() );
|
||||||
CHAIN_END( e, "Critical error while initializing, abort." );
|
CHAIN_END( e, "Critical error while initializing, abort." );
|
||||||
|
if (!foreground_mode) {
|
||||||
|
/* Tell to parent that startup went OK. */
|
||||||
|
wave_to_parent (parent_pid);
|
||||||
|
}
|
||||||
|
drop_privs(user); /* This can't be done before, because sending a
|
||||||
|
signal to a process of a different user will fail */
|
||||||
|
|
||||||
do_mainloop();
|
do_mainloop();
|
||||||
/* This loop never stops; we'll get out only with a signal...*/
|
/* This loop never stops; we'll get out only with a signal...*/
|
||||||
@@ -241,11 +250,11 @@ clear_settings ()
|
|||||||
|
|
||||||
debug( RPT_DEBUG, "%s()", __FUNCTION__ );
|
debug( RPT_DEBUG, "%s()", __FUNCTION__ );
|
||||||
|
|
||||||
lcd_port = UNSET_INT;
|
bind_port = UNSET_INT;
|
||||||
strncpy( bind_addr, UNSET_STR, sizeof(bind_addr) );
|
strncpy( bind_addr, UNSET_STR, sizeof(bind_addr) );
|
||||||
strncpy( configfile, UNSET_STR, sizeof(configfile) );
|
strncpy( configfile, UNSET_STR, sizeof(configfile) );
|
||||||
strncpy( user, UNSET_STR, sizeof(user) );
|
strncpy( user, UNSET_STR, sizeof(user) );
|
||||||
daemon_mode = UNSET_INT;
|
foreground_mode = UNSET_INT;
|
||||||
rotate_server_screen = UNSET_INT;
|
rotate_server_screen = UNSET_INT;
|
||||||
backlight = UNSET_INT;
|
backlight = UNSET_INT;
|
||||||
|
|
||||||
@@ -303,7 +312,7 @@ process_command_line (int argc, char **argv)
|
|||||||
report( RPT_ERR, "Not a boolean value: '%s'", optarg );
|
report( RPT_ERR, "Not a boolean value: '%s'", optarg );
|
||||||
e = -1;
|
e = -1;
|
||||||
} else {
|
} else {
|
||||||
daemon_mode = !b;
|
foreground_mode = b;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
@@ -311,7 +320,7 @@ process_command_line (int argc, char **argv)
|
|||||||
bind_addr[sizeof(bind_addr)-1] = 0; /* Terminate string */
|
bind_addr[sizeof(bind_addr)-1] = 0; /* Terminate string */
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
lcd_port = atoi(optarg);
|
bind_port = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
strncpy(user, optarg, sizeof(user));
|
strncpy(user, optarg, sizeof(user));
|
||||||
@@ -385,8 +394,8 @@ process_configfile ( char *configfile )
|
|||||||
report( RPT_WARNING, "Could not read config file: %s", configfile );
|
report( RPT_WARNING, "Could not read config file: %s", configfile );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( lcd_port == UNSET_INT )
|
if( bind_port == UNSET_INT )
|
||||||
lcd_port = config_get_int( "server", "port", 0, UNSET_INT );
|
bind_port = config_get_int( "server", "port", 0, UNSET_INT );
|
||||||
|
|
||||||
if( strcmp( bind_addr, UNSET_STR ) == 0 )
|
if( strcmp( bind_addr, UNSET_STR ) == 0 )
|
||||||
strncpy( bind_addr, config_get_string( "server", "bind", 0, UNSET_STR ), sizeof(bind_addr));
|
strncpy( bind_addr, config_get_string( "server", "bind", 0, UNSET_STR ), sizeof(bind_addr));
|
||||||
@@ -404,11 +413,11 @@ process_configfile ( char *configfile )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( daemon_mode == UNSET_INT ) {
|
if( foreground_mode == UNSET_INT ) {
|
||||||
int fg;
|
int fg;
|
||||||
fg = config_get_bool( "server", "foreground", 0, UNSET_INT );
|
fg = config_get_bool( "server", "foreground", 0, UNSET_INT );
|
||||||
if( fg != UNSET_INT )
|
if( fg != UNSET_INT )
|
||||||
daemon_mode = !fg;
|
foreground_mode = fg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( rotate_server_screen == UNSET_INT ) {
|
if( rotate_server_screen == UNSET_INT ) {
|
||||||
@@ -470,15 +479,15 @@ set_default_settings()
|
|||||||
|
|
||||||
/* Set defaults into unfilled variables....*/
|
/* Set defaults into unfilled variables....*/
|
||||||
|
|
||||||
if (lcd_port == UNSET_INT)
|
if (bind_port == UNSET_INT)
|
||||||
lcd_port = DEFAULT_BIND_PORT;
|
bind_port = DEFAULT_BIND_PORT;
|
||||||
if (strcmp( bind_addr, UNSET_STR ) == 0)
|
if (strcmp( bind_addr, UNSET_STR ) == 0)
|
||||||
strncpy (bind_addr, DEFAULT_BIND_ADDR, sizeof(bind_addr));
|
strncpy (bind_addr, DEFAULT_BIND_ADDR, sizeof(bind_addr));
|
||||||
if (strcmp( user, UNSET_STR ) == 0)
|
if (strcmp( user, UNSET_STR ) == 0)
|
||||||
strncpy(user, DEFAULT_USER, sizeof(user));
|
strncpy(user, DEFAULT_USER, sizeof(user));
|
||||||
|
|
||||||
if (daemon_mode == UNSET_INT)
|
if (foreground_mode == UNSET_INT)
|
||||||
daemon_mode = DEFAULT_DAEMON_MODE;
|
foreground_mode = DEFAULT_FOREGROUND_MODE;
|
||||||
if (rotate_server_screen == UNSET_INT)
|
if (rotate_server_screen == UNSET_INT)
|
||||||
rotate_server_screen = DEFAULT_ROTATE_SERVER_SCREEN;
|
rotate_server_screen = DEFAULT_ROTATE_SERVER_SCREEN;
|
||||||
|
|
||||||
@@ -502,52 +511,112 @@ set_default_settings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
void
|
||||||
|
install_signal_handlers (int allow_reload)
|
||||||
|
{
|
||||||
|
/* Installs signal handlers so that the program does clean exit and
|
||||||
|
* can also receive a reload signal.
|
||||||
|
* sigaction() is favoured over signal() */
|
||||||
|
|
||||||
|
struct sigaction sa;
|
||||||
|
|
||||||
|
debug( RPT_DEBUG, "%s( allow_reload=%d )", __FUNCTION__, allow_reload );
|
||||||
|
|
||||||
|
sa.sa_handler = exit_program;
|
||||||
|
sigemptyset ( &(sa.sa_mask) );
|
||||||
|
sa.sa_flags = SA_RESTART;
|
||||||
|
|
||||||
|
sigaction (SIGINT, &sa, NULL); /* Ctrl-C will cause a clean exit...*/
|
||||||
|
sigaction (SIGTERM, &sa, NULL); /* and "kill"...*/
|
||||||
|
|
||||||
|
if (allow_reload) {
|
||||||
|
sa.sa_handler = catch_reload_signal;
|
||||||
|
/* On SIGHUP reread config and restart the drivers ! */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Treat this signal just like INT and TERM */
|
||||||
|
}
|
||||||
|
sigaction (SIGHUP, &sa, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
child_ok_func (int signal) {
|
||||||
|
/* We only catch this signal to be sure the child runs OK. */
|
||||||
|
|
||||||
|
debug( RPT_INFO, "%s( signal=%d )", __FUNCTION__, signal );
|
||||||
|
|
||||||
|
/* Exit now ! because of bug? in wait() */
|
||||||
|
_exit( 0 ); /* Parent exits normally. */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pid_t
|
||||||
daemonize()
|
daemonize()
|
||||||
{
|
{
|
||||||
int child;
|
pid_t child;
|
||||||
|
pid_t parent;
|
||||||
|
int child_status;
|
||||||
|
struct sigaction sa;
|
||||||
|
|
||||||
debug( RPT_DEBUG, "%s()", __FUNCTION__ );
|
debug( RPT_DEBUG, "%s()", __FUNCTION__ );
|
||||||
|
|
||||||
|
parent = getpid();
|
||||||
|
debug( RPT_INFO, "parent = %d", parent );
|
||||||
|
|
||||||
|
/* Install handler at parent for child's signal */
|
||||||
|
/* sigaction should be more portable than signal, but it does not
|
||||||
|
* work for some reason. */
|
||||||
|
sa.sa_handler = child_ok_func;
|
||||||
|
sigemptyset ( &(sa.sa_mask) );
|
||||||
|
sa.sa_flags = SA_RESTART;
|
||||||
|
sigaction (SIGUSR1, &sa, NULL);
|
||||||
|
|
||||||
|
/* Do the fork */
|
||||||
switch ((child = fork ()) ) {
|
switch ((child = fork ()) ) {
|
||||||
case -1:
|
case -1:
|
||||||
report(RPT_ERR, "Could not fork");
|
report( RPT_ERR, "Could not fork" );
|
||||||
return -1;
|
return -1;
|
||||||
case 0: /* We are the child*/
|
case 0: /* We are the child */
|
||||||
break;
|
break;
|
||||||
default: /* We are the parent*/
|
default: /* We are the parent */
|
||||||
usleep (1500000); /* Wait for child to initialize*/
|
debug( RPT_INFO, "child = %d", child );
|
||||||
exit (0); /* PARENT EXITS */
|
wait( &child_status );
|
||||||
|
/* BUG? According to the man page wait() should also return
|
||||||
|
* when a signal comes in that is caught. Instead it
|
||||||
|
* continues to wait. */
|
||||||
|
|
||||||
|
if( WIFEXITED(child_status) ) {
|
||||||
|
/* Child exited normally, probably because of some
|
||||||
|
* error. */
|
||||||
|
debug( RPT_INFO, "Child has terminated!" );
|
||||||
|
exit( WEXITSTATUS(child_status) );
|
||||||
|
/* Parent exits with same status as child did... */
|
||||||
|
}
|
||||||
|
/* Child is still running and has signalled it's OK.
|
||||||
|
* This means the parent can now rest in peace. */
|
||||||
|
debug( RPT_INFO, "Got OK signal from child." );
|
||||||
|
exit( 0 ); /* Parent exits normally. */
|
||||||
}
|
}
|
||||||
/* This line removed because it eats error messages...
|
/* At this point we are always the child. */
|
||||||
* setsid();*/ /* RELEASE TTY */
|
/* Reset signal handler */
|
||||||
/*
|
sa.sa_handler = SIG_DFL;
|
||||||
* After this point, as a daemon, no error messages should
|
sigaction (SIGUSR1, &sa, NULL);
|
||||||
* go to the console unless drastic; rather, they should go to syslog
|
|
||||||
*
|
setsid(); /* Create a new session because otherwise we'll
|
||||||
* However, option processing is not yet done, nor is any initialization (!)
|
* catch a SIGHUP when the shell is closed. */
|
||||||
* So we must wait until the main loop.
|
|
||||||
*/
|
return parent;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
init_sockets ()
|
wave_to_parent (pid_t parent_pid)
|
||||||
{
|
{
|
||||||
debug( RPT_DEBUG, "%s()", __FUNCTION__ );
|
debug( RPT_DEBUG, "%s( parent_pid=%d )", __FUNCTION__, parent_pid );
|
||||||
|
|
||||||
if (sock_create_server (&bind_addr, lcd_port) <= 0) {
|
kill( parent_pid, SIGUSR1 );
|
||||||
report(RPT_ERR, "Error opening socket");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now init a bunch of required stuff...*/
|
|
||||||
|
|
||||||
if (clients_init () < 0) {
|
|
||||||
report(RPT_ERR, "Error initializing client list");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,9 +643,7 @@ init_drivers()
|
|||||||
output_loaded = 1;
|
output_loaded = 1;
|
||||||
break;
|
break;
|
||||||
case 2: /* Driver does output in foreground (don't daemonize) */
|
case 2: /* Driver does output in foreground (don't daemonize) */
|
||||||
if ( !output_loaded ) {
|
foreground_mode = 1;
|
||||||
daemon_mode = 0;
|
|
||||||
}
|
|
||||||
output_loaded = 1;
|
output_loaded = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -782,6 +849,7 @@ exit_program (int val)
|
|||||||
screenlist_shutdown (); /* shutdown screens (must come after client_shutdown) */
|
screenlist_shutdown (); /* shutdown screens (must come after client_shutdown) */
|
||||||
input_shutdown (); /* shutdown key input part */
|
input_shutdown (); /* shutdown key input part */
|
||||||
|
|
||||||
|
report( RPT_INFO, "Exiting." );
|
||||||
_exit (0);
|
_exit (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,4 +42,29 @@ extern long int timer;
|
|||||||
* If you get an overflow, please mail us and we will fix this personally
|
* If you get an overflow, please mail us and we will fix this personally
|
||||||
* for you ! */
|
* for you ! */
|
||||||
|
|
||||||
|
/**** Configuration variables ****/
|
||||||
|
/* Only configuration items that are settable from the command line should
|
||||||
|
* be mentioned here. See main.c.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern unsigned int bind_port;
|
||||||
|
extern char bind_addr[]; /* Do not preinit these strings as they will occupy */
|
||||||
|
extern char configfile[]; /* a lot of space in the executable. */
|
||||||
|
extern char user[]; /* The values will be overwritten anyway... */
|
||||||
|
|
||||||
|
extern int foreground_mode;
|
||||||
|
|
||||||
|
extern int report_level;
|
||||||
|
extern int report_to_syslog;
|
||||||
|
|
||||||
|
/* The drivers and their driver parameters */
|
||||||
|
extern char *drivernames[];
|
||||||
|
extern int num_drivers;
|
||||||
|
|
||||||
|
/* End of configuration variables */
|
||||||
|
|
||||||
|
/* Defines for having 'unset' values*/
|
||||||
|
#define UNSET_INT -1
|
||||||
|
#define UNSET_STR "\01"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+52
-49
@@ -32,6 +32,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "shared/sockets.h"
|
#include "shared/sockets.h"
|
||||||
|
#include "main.h"
|
||||||
#include "sock.h"
|
#include "sock.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "clients.h"
|
#include "clients.h"
|
||||||
@@ -39,19 +40,57 @@
|
|||||||
#include "shared/report.h"
|
#include "shared/report.h"
|
||||||
#include "screenlist.h"
|
#include "screenlist.h"
|
||||||
|
|
||||||
extern char bind_addr[64];
|
|
||||||
extern int lcd_port;
|
|
||||||
|
|
||||||
|
|
||||||
fd_set active_fd_set, read_fd_set;
|
fd_set active_fd_set, read_fd_set;
|
||||||
int orig_sock;
|
int listening_fd;
|
||||||
|
|
||||||
/* Length of longest transmission allowed at once...*/
|
/* Length of longest transmission allowed at once...*/
|
||||||
#define MAXMSG 8192
|
#define MAXMSG 8192
|
||||||
|
|
||||||
int read_from_client (int filedes);
|
int sock_read_from_client (int filedes);
|
||||||
|
|
||||||
/* Creates a socket in internet space*/
|
|
||||||
|
int
|
||||||
|
sock_init ()
|
||||||
|
{
|
||||||
|
debug (RPT_DEBUG, "%s( bind_addr=\"%s\", port=%d )", __FUNCTION__, bind_addr, bind_port);
|
||||||
|
|
||||||
|
/* Create the socket and set it up to accept connections. */
|
||||||
|
listening_fd = sock_create_inet_socket (bind_addr, bind_port);
|
||||||
|
if (listening_fd < 0) {
|
||||||
|
report (RPT_ERR, "%s: Error creating socket", __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This code gets the send and receive buffer sizes.
|
||||||
|
{
|
||||||
|
int val, len, sock;
|
||||||
|
sock = new;
|
||||||
|
|
||||||
|
len = sizeof(int);
|
||||||
|
getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &val, &len);
|
||||||
|
debug(RPT_DEBUG, "SEND buffer: %i bytes", val);
|
||||||
|
|
||||||
|
len = sizeof(int);
|
||||||
|
getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &val, &len);
|
||||||
|
debug(RPT_DEBUG, "RECV buffer: %i bytes", val);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
sock_shutdown ()
|
||||||
|
{
|
||||||
|
debug( RPT_DEBUG, "%s()", __FUNCTION__ );
|
||||||
|
|
||||||
|
close( listening_fd );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Creates a socket in internet space */
|
||||||
int
|
int
|
||||||
sock_create_inet_socket (char * addr, unsigned int port)
|
sock_create_inet_socket (char * addr, unsigned int port)
|
||||||
{
|
{
|
||||||
@@ -61,7 +100,6 @@ sock_create_inet_socket (char * addr, unsigned int port)
|
|||||||
debug (RPT_DEBUG, "%s( addr=\"%s\", port=%i )", __FUNCTION__, addr, port);
|
debug (RPT_DEBUG, "%s( addr=\"%s\", port=%i )", __FUNCTION__, addr, port);
|
||||||
|
|
||||||
/* Create the socket. */
|
/* Create the socket. */
|
||||||
/*debug(RPT_DEBUG, "Creating Inet Socket");*/
|
|
||||||
sock = socket (PF_INET, SOCK_STREAM, 0);
|
sock = socket (PF_INET, SOCK_STREAM, 0);
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
report(RPT_ERR, "%s: Could not create socket", __FUNCTION__);
|
report(RPT_ERR, "%s: Could not create socket", __FUNCTION__);
|
||||||
@@ -86,25 +124,6 @@ sock_create_inet_socket (char * addr, unsigned int port)
|
|||||||
report(RPT_NOTICE, "Listening for queries on %s:%d", addr, port);
|
report(RPT_NOTICE, "Listening for queries on %s:%d", addr, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sock;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*int StartSocketServer()*/
|
|
||||||
int
|
|
||||||
sock_create_server (char *bind_addr, int lcd_port)
|
|
||||||
{
|
|
||||||
int sock;
|
|
||||||
|
|
||||||
debug (RPT_DEBUG, "%s( bind_addr=\"%s\", port=%d )", __FUNCTION__, bind_addr, lcd_port);
|
|
||||||
|
|
||||||
/* Create the socket and set it up to accept connections. */
|
|
||||||
sock = sock_create_inet_socket (bind_addr, lcd_port);
|
|
||||||
if (sock < 0) {
|
|
||||||
report (RPT_ERR, "%s: Error creating socket", __FUNCTION__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listen (sock, 1) < 0) {
|
if (listen (sock, 1) < 0) {
|
||||||
report(RPT_ERR, "%s: error in attempting to listen to port", __FUNCTION__);
|
report(RPT_ERR, "%s: error in attempting to listen to port", __FUNCTION__);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -114,28 +133,11 @@ sock_create_server (char *bind_addr, int lcd_port)
|
|||||||
FD_ZERO (&active_fd_set);
|
FD_ZERO (&active_fd_set);
|
||||||
FD_SET (sock, &active_fd_set);
|
FD_SET (sock, &active_fd_set);
|
||||||
|
|
||||||
orig_sock = sock;
|
|
||||||
|
|
||||||
/*
|
|
||||||
{
|
|
||||||
int val, len, sock;
|
|
||||||
sock = new;
|
|
||||||
|
|
||||||
len = sizeof(int);
|
|
||||||
getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &val, &len);
|
|
||||||
debug(RPT_DEBUG, "SEND buffer: %i bytes", val);
|
|
||||||
|
|
||||||
len = sizeof(int);
|
|
||||||
getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &val, &len);
|
|
||||||
debug(RPT_DEBUG, "RECV buffer: %i bytes", val);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Service all clients with input pending...*/
|
|
||||||
|
|
||||||
|
/* Service all clients with input pending...*/
|
||||||
int
|
int
|
||||||
sock_poll_clients ()
|
sock_poll_clients ()
|
||||||
{
|
{
|
||||||
@@ -162,11 +164,11 @@ sock_poll_clients ()
|
|||||||
/* Service all the sockets with input pending. */
|
/* Service all the sockets with input pending. */
|
||||||
for (i = 0; i < FD_SETSIZE; ++i) {
|
for (i = 0; i < FD_SETSIZE; ++i) {
|
||||||
if (FD_ISSET (i, &read_fd_set)) {
|
if (FD_ISSET (i, &read_fd_set)) {
|
||||||
if (i == orig_sock) {
|
if (i == listening_fd) {
|
||||||
/* Connection request on original socket. */
|
/* Connection request on original socket. */
|
||||||
int new_sock;
|
int new_sock;
|
||||||
size = sizeof (clientname);
|
size = sizeof (clientname);
|
||||||
new_sock = accept (orig_sock, (struct sockaddr *) &clientname, &size);
|
new_sock = accept (listening_fd, (struct sockaddr *) &clientname, &size);
|
||||||
if (new_sock < 0) {
|
if (new_sock < 0) {
|
||||||
report (RPT_ERR, "%s: Accept error", __FUNCTION__);
|
report (RPT_ERR, "%s: Accept error", __FUNCTION__);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -191,7 +193,7 @@ sock_poll_clients ()
|
|||||||
err = 0;
|
err = 0;
|
||||||
do {
|
do {
|
||||||
debug (RPT_DEBUG, "%s: reading...", __FUNCTION__);
|
debug (RPT_DEBUG, "%s: reading...", __FUNCTION__);
|
||||||
err = read_from_client (i);
|
err = sock_read_from_client (i);
|
||||||
debug (RPT_DEBUG, "%s: ...done", __FUNCTION__);
|
debug (RPT_DEBUG, "%s: ...done", __FUNCTION__);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
/* Client disconnected, destroy client data */
|
/* Client disconnected, destroy client data */
|
||||||
@@ -203,8 +205,9 @@ sock_poll_clients ()
|
|||||||
clients_remove_client (c);
|
clients_remove_client (c);
|
||||||
close (i);
|
close (i);
|
||||||
FD_CLR (i, &active_fd_set);
|
FD_CLR (i, &active_fd_set);
|
||||||
} else
|
} else {
|
||||||
report (RPT_ERR, "%s: Can't find client of socket %i", __FUNCTION__, i);
|
report (RPT_ERR, "%s: Can't find client of socket %i", __FUNCTION__, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (err > 0);
|
} while (err > 0);
|
||||||
}
|
}
|
||||||
@@ -214,7 +217,7 @@ sock_poll_clients ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
read_from_client (int filedes)
|
sock_read_from_client (int filedes)
|
||||||
{
|
{
|
||||||
char buffer[MAXMSG];
|
char buffer[MAXMSG];
|
||||||
int nbytes, i;
|
int nbytes, i;
|
||||||
|
|||||||
+5
-5
@@ -9,17 +9,17 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SOCKETS_H
|
#ifndef SOCK_H
|
||||||
#define SOCKETS_H
|
#define SOCK_H
|
||||||
|
|
||||||
#include "shared/sockets.h"
|
#include "shared/sockets.h"
|
||||||
|
|
||||||
typedef struct sockaddr_in sockaddr_in;
|
typedef struct sockaddr_in sockaddr_in;
|
||||||
|
|
||||||
/* Server functions...*/
|
/* Server functions...*/
|
||||||
int sock_create_server ();
|
int sock_init ();
|
||||||
int sock_create_inet_socket (unsigned short int port);
|
int sock_shutdown ();
|
||||||
|
int sock_create_inet_socket (char * addr, unsigned int port);
|
||||||
int sock_poll_clients ();
|
int sock_poll_clients ();
|
||||||
int read_from_client (int filedes);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user