diff options
author | Andreas Baumann <abaumann@yahoo.com> | 2008-12-21 14:48:47 +0100 |
---|---|---|
committer | Andreas Baumann <abaumann@yahoo.com> | 2008-12-21 14:48:47 +0100 |
commit | 01e67d010b9badcf2ffc65d74b0f9285f26d45e5 (patch) | |
tree | 0dba70ed0cd51e57d8a928f001e5b224efecb203 /tests/daemon | |
parent | 19fcd209c75df389602869520a67ee065fd5cfbf (diff) | |
download | wolfbones-01e67d010b9badcf2ffc65d74b0f9285f26d45e5.tar.gz wolfbones-01e67d010b9badcf2ffc65d74b0f9285f26d45e5.tar.bz2 |
much more cleanup, trying to split things without violating rmch
Diffstat (limited to 'tests/daemon')
-rw-r--r-- | tests/daemon/testd.c | 158 | ||||
-rw-r--r-- | tests/daemon/testd.conf | 14 | ||||
-rw-r--r-- | tests/daemon/testd.ggo | 70 |
3 files changed, 242 insertions, 0 deletions
diff --git a/tests/daemon/testd.c b/tests/daemon/testd.c new file mode 100644 index 0000000..7d8fafb --- /dev/null +++ b/tests/daemon/testd.c @@ -0,0 +1,158 @@ +#include "port/stdbool.h" /* for bool */ +#include "port/string.h" /* for memset */ + +#include <sys/types.h> /* for pid_t */ +#include <unistd.h> /* for exit, unistd, getuid, getppid */ +#include <stdlib.h> /* for EXIT_FAILURE */ + +#include "errors.h" /* global error codes */ +#include "log.h" /* logging facility */ +#include "daemon.h" /* Unix daemonizing code */ +#include "signals.h" /* signal supension */ + +#include "port/unused.h" + +#include "testd_cmdline.h" /* for command line and option parsing (gengetopt) */ + +#define DEFAULT_CONFIG_FILE "/etc/" CMDLINE_PARSER_PACKAGE ".conf" + +static int parse_options_and_arguments( int argc, char *argv[], struct gengetopt_args_info *args_info ) { + cmdline_parser_init( args_info ); + + if( cmdline_parser2( argc, argv, args_info, 1, 0, 1 ) != 0 ) { + cmdline_parser_free( args_info ); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static int test_config( const char *filename ) { + UNUSED( filename ); + return EXIT_SUCCESS; +} + +static int read_config( const char *filename, struct gengetopt_args_info *args_info ) { + char *config_filename = strdup( filename ); + if( cmdline_parser_configfile( config_filename, args_info, 1, 0, 1 ) != 0 ) { + fprintf( stderr, "\n%s\n", gengetopt_args_info_usage ); + cmdline_parser_free( args_info ); + free( config_filename ); + return EXIT_FAILURE; + } + free( config_filename ); + + return EXIT_SUCCESS; +} + +int main( int argc, char *argv[] ) { + struct gengetopt_args_info args_info; + error_t error; + daemon_params_t daemon_params; + daemon_p demon = NULL; + int sig = 0; + + if( parse_options_and_arguments( argc, argv, &args_info ) == EXIT_FAILURE ) { + exit( EXIT_FAILURE ); + } + + if( read_config( args_info.config_file_given ? + args_info.config_file_arg : DEFAULT_CONFIG_FILE, &args_info ) == EXIT_FAILURE ) { + exit( EXIT_FAILURE ); + } + + if( args_info.test_given ) { + cmdline_parser_free( &args_info ); + exit( test_config( args_info.config_file_given ? + args_info.config_file_arg : DEFAULT_CONFIG_FILE ) ); + } + + openlogtostderr( LOG_DEBUG - 1 + (int)args_info.debug_given ); + if( args_info.logfile_given ) + openlogtofile( args_info.logfile_arg, + args_info.logfile_level_given ? + log_str_to_level( args_info.logfile_level_arg ) : LOG_NOTICE ); + + if( !args_info.foreground_given ) { + openlogtosyslog( CMDLINE_PARSER_PACKAGE, + args_info.syslog_facility_given ? + log_str_to_syslog_facility( args_info.syslog_facility_arg ) : LOG_DAEMON, + args_info.syslog_level_given ? + log_str_to_level( args_info.syslog_level_arg ) : LOG_NOTICE ); + + memset( &daemon_params, 0, sizeof( daemon_params ) ); + daemon_params.daemon_name = CMDLINE_PARSER_PACKAGE; + daemon_params.pid_filename = args_info.pidfile_given ? + args_info.pidfile_arg : NULL; + daemon_params.group_name = args_info.group_given ? + args_info.group_arg : NULL; + daemon_params.user_name = args_info.user_given ? + args_info.user_arg : NULL; + + demon = daemon_new( daemon_params, &error ); + if( demon == NULL ) { + cmdline_parser_free( &args_info ); + exit( EXIT_FAILURE ); + } + + if( ( error = daemon_start( demon ) ) != OK ) { + cmdline_parser_free( &args_info ); + daemon_exit( demon ); + } + } else { + if( ( error = signal_initialize( ) ) != OK ) { + cmdline_parser_free( &args_info ); + exit( EXIT_FAILURE ); + } + if( ( error = signal_install_handlers_daemon( ) ) != OK ) { + signal_terminate( ); + cmdline_parser_free( &args_info ); + exit( EXIT_FAILURE ); + } + } + + LOG( LOG_NOTICE, "Started %s daemon", CMDLINE_PARSER_PACKAGE ); + while( ( sig != SIGTERM ) && ( sig != SIGINT ) && ( sig != -1 ) ) { + sig = signal_suspend( 60, &error ); + switch( sig ) { + case 0: /* timeout */ + break; + + case -1: /* internal error */ + break; + + case SIGHUP: + LOG( LOG_NOTICE, "Rereading configuration" ); + break; + + case SIGTERM: + case SIGINT: + LOG( LOG_NOTICE, "Got termination signal, shutting down the daemon" ); + break; + + case SIGUSR1: + break; + + case SIGUSR2: + break; + + default: + LOG( LOG_ERR, "Unexpected signal '%s' (%s, %d)", + signal_get_long_name( sig ), + signal_get_short_name( sig ), + sig ); + } + } + LOG( LOG_NOTICE, "Stopped %s daemon", CMDLINE_PARSER_PACKAGE ); + + if( !args_info.foreground_given ) { + cmdline_parser_free( &args_info ); + daemon_exit( demon ); + } else { + cmdline_parser_free( &args_info ); + signal_terminate( ); + exit( EXIT_SUCCESS ); + } + + exit( EXIT_FAILURE ); +} diff --git a/tests/daemon/testd.conf b/tests/daemon/testd.conf new file mode 100644 index 0000000..4fe43e5 --- /dev/null +++ b/tests/daemon/testd.conf @@ -0,0 +1,14 @@ +# Unpriviledged User and group the daemon should run as +user = daemon +group = daemon + +# Where to write the PID of the daemon process +pidfile = /var/run/testd.pid + +# Logging to system log facility (syslog) +syslog-facility = DAEMON +syslog-level = NOTICE + +# Logging to a plain text file +logfile = /var/log/testd.log +logfile-level = NOTICE diff --git a/tests/daemon/testd.ggo b/tests/daemon/testd.ggo new file mode 100644 index 0000000..08c83cb --- /dev/null +++ b/tests/daemon/testd.ggo @@ -0,0 +1,70 @@ +package "testd" +version "0.0.1" +usage "testd [options]" +description "tests daemonizing on Unix without any functionality\n" + +section "Main Options" + option "foreground" f + "Do not daemonize, run in foreground, write to stdout/stderr" + optional + + option "config-file" c + "The location of the configuration file of the daemon" + string typestr="file" + optional + + option "debug" d + "Increase debug level (option can be given many times)" + optional multiple hidden + + option "test" t + "Test the configuration without running the daemon" + optional + +section "Query Options" + option "list-modules" - + "List loaded modules" + optional hidden + +section "Daemon Options" + option "user" u + "User the daemon should run as" + string typestr="user" + optional hidden + + option "group" g + "Group the daemon should run as" + string typestr="group" + optional hidden + + option "pidfile" - + "Location of the pidfile (explicitly, normaly the system knows where to store them)" + string typestr="file" + optional hidden + + option "syslog-facility" - + "System log facility to use for logging to system log" + optional hidden + typestr="facility" + values="KERN","USER","MAIL","DAEMON","AUTH","SYSLOG","LPR","NEWS","UUCP","CRON","AUTHPRIV","FTP" + default="DAEMON" + + option "syslog-level" - + "Level for logging to system log" + optional hidden + typestr="level" + values="EMERG","ALERT","CRIT","ERR","WARNING","NOTICE","INFO","DEBUG","DEBUG1","DEBUG2","DEBUG3","DEBUG4","DEBUG5" + default="NOTICE" + + option "logfile" - + "Name of a log file where to log to" + string typestr="file" + optional hidden + + option "logfile-level" - + "Level for logging to the logfile" + optional hidden + typestr="level" + values="EMERG","ALERT","CRIT","ERR","WARNING","NOTICE","INFO","DEBUG","DEBUG1","DEBUG2","DEBUG3","DEBUG4","DEBUG5" + default="NOTICE" + |