summaryrefslogtreecommitdiff
path: root/tests/daemon
diff options
context:
space:
mode:
authorAndreas Baumann <abaumann@yahoo.com>2008-12-21 14:48:47 +0100
committerAndreas Baumann <abaumann@yahoo.com>2008-12-21 14:48:47 +0100
commit01e67d010b9badcf2ffc65d74b0f9285f26d45e5 (patch)
tree0dba70ed0cd51e57d8a928f001e5b224efecb203 /tests/daemon
parent19fcd209c75df389602869520a67ee065fd5cfbf (diff)
downloadwolfbones-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.c158
-rw-r--r--tests/daemon/testd.conf14
-rw-r--r--tests/daemon/testd.ggo70
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"
+