From 41de6aa9e0e72ef6fa5689c319f30e70841304a4 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Fri, 21 Mar 2008 10:55:01 +0100 Subject: [PATCH] Issue 31: Add custom config module --- acinclude.m4 | 74 ----------- configure.in | 14 +- contrib/etc/remote-mch.cfg | 6 +- contrib/etc/remote-mcs.cfg | 4 +- doc/remote-device-add.7 | 6 +- doc/remote-device-name.7 | 6 +- doc/remote-device-remove.7 | 6 +- doc/remote-mch.1 | 67 +++++++--- doc/remote-mch.1.txt | 66 ++++++++-- doc/remote-mcs.1 | 69 +++++++--- doc/remote-mcs.1.txt | 66 +++++++--- libutil/Config.cc | 310 +++++++++++++++++++++++++++++++++++++++++++++ libutil/Config.h | 131 +++++++++++++++++++ libutil/Makefile.am | 1 + mch/Configuration.cc | 79 ------------ mch/Configuration.h | 43 ------- mch/Makefile.am | 5 +- mch/MoteHost.cc | 55 +++++--- mch/MoteHost.h | 13 +- mcs/Configuration.cc | 90 ------------- mcs/Configuration.h | 40 ------ mcs/Makefile.am | 5 +- mcs/moteserver.cc | 61 ++++++--- 23 files changed, 753 insertions(+), 464 deletions(-) create mode 100644 libutil/Config.cc create mode 100644 libutil/Config.h delete mode 100644 mch/Configuration.cc delete mode 100644 mch/Configuration.h delete mode 100644 mcs/Configuration.cc delete mode 100644 mcs/Configuration.h diff --git a/acinclude.m4 b/acinclude.m4 index 9d7f383..08d2937 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -15,80 +15,6 @@ # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. -# {{{ Boost program options - -AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS], -[ -AC_ARG_WITH([boost-program-options], - AS_HELP_STRING([--with-boost-program-options@<:@=special-lib@:>@], - [use the program options library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-program-options=boost_program_options-gcc-mt-1_33_1 ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_program_options_lib="" - else - want_boost="yes" - ax_boost_user_program_options_lib="$withval" - fi - ], - [want_boost="yes"] -) - -CONFIG_BOOST_PROGRAM_OPTIONS=no - -if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - export want_boost - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_CACHE_CHECK([whether the Boost::Program_Options library is available], - ax_cv_boost_program_options, - [AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[@%:@include - ]], - [[boost::program_options::options_description generic("Generic options")]]), - ax_cv_boost_program_options=yes, - ax_cv_boost_program_options=no) - AC_LANG_POP([C++]) - ]) - if test "$ax_cv_boost_program_options" = yes; then - AC_DEFINE(HAVE_BOOST_PROGRAM_OPTIONS,[1],[Define if the Boost::PROGRAM_OPTIONS library is available]) - BN=boost_program_options - AC_LANG_PUSH(C++) - if test "x$ax_boost_user_program_options_lib" = "x"; then - for ax_lib in $BN $BN-$CC $BN-$CC-mt $BN-$CC-mt-s $BN-$CC-s \ - lib$BN lib$BN-$CC lib$BN-$CC-mt lib$BN-$CC-mt-s lib$BN-$CC-s \ - $BN-mgw $BN-mgw $BN-mgw-mt $BN-mgw-mt-s $BN-mgw-s ; do - AC_CHECK_LIB($ax_lib, main, - [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) CONFIG_BOOST_PROGRAM_OPTIONS="yes"; break], - [CONFIG_BOOST_PROGRAM_OPTIONS="no"]) - done - else - for ax_lib in $ax_boost_user_program_options_lib $BN-$ax_boost_user_program_options_lib; do - AC_CHECK_LIB($ax_lib, main, - [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) CONFIG_BOOST_PROGRAM_OPTIONS="yes"; break], - [CONFIG_BOOST_PROGRAM_OPTIONS="no"]) - done - fi - AC_LANG_POP([C++]) - if test "x$CONFIG_BOOST_PROGRAM_OPTIONS" = "xno"; then - AC_MSG_ERROR([Could not link against [$ax_lib] !]) - fi - fi - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" -fi -]) - -# }}} # {{{ MySQL AC_DEFUN([AX_LIB_MYSQL], diff --git a/configure.in b/configure.in index ed19e77..120d783 100644 --- a/configure.in +++ b/configure.in @@ -56,7 +56,6 @@ AM_CONDITIONAL(CONFIG_MAN, test "x$ASCIIDOC" != "x:" && test "x$XMLTO" != "x:") ## Checks for libraries. ####################################################################### -AX_BOOST_PROGRAM_OPTIONS AX_LIB_MYSQL AX_LIB_MYSQLPP @@ -124,20 +123,10 @@ AC_TYPE_SIGNAL ## Check dependencies. ####################################################################### -if test "x$CONFIG_MCH" = "xyes"; then - if test "x$CONFIG_BOOST_PROGRAM_OPTIONS" != "xyes"; then - if test "x$enable_mch" = "xyes"; then - AC_MSG_ERROR([MCH dependencies not found on the system]) - else - CONFIG_MCH=no - fi - fi -fi AM_CONDITIONAL(CONFIG_MCH, test "x$CONFIG_MCH" = "xyes") if test "x$CONFIG_MCS" = "xyes"; then - if test "x$CONFIG_BOOST_PROGRAM_OPTIONS" != "xyes" || - test "x$CONFIG_MYSQL" != "xyes" || + if test "x$CONFIG_MYSQL" != "xyes" || test "x$CONFIG_MYSQLPP" != "xyes"; then if test "x$enable_mcs" = "xyes"; then AC_MSG_ERROR([MCS dependencies not found on the system]) @@ -168,7 +157,6 @@ AC_OUTPUT ####################################################################### AC_MSG_RESULT([Found dependencies:]) -AC_MSG_RESULT([ Boost program option library .... $CONFIG_BOOST_PROGRAM_OPTIONS]) AC_MSG_RESULT([ MySQL library ................... $CONFIG_MYSQL]) AC_MSG_RESULT([ MySQL++ library ................. $CONFIG_MYSQLPP]) AC_MSG_RESULT([Will build:]) diff --git a/contrib/etc/remote-mch.cfg b/contrib/etc/remote-mch.cfg index ef819f8..c119bb4 100644 --- a/contrib/etc/remote-mch.cfg +++ b/contrib/etc/remote-mch.cfg @@ -1,13 +1,13 @@ ############ Server connection options # DNS or IP address of the mote server. -serverAddress = "localhost" +serverHost = "localhost" # Port number for connecting to the mote server. serverPort = 10001 # Number of seconds to wait between server connection retries. -serverConnectionRetryInterval = 30 +retryInterval = 30 ############ Mote device related options @@ -15,4 +15,4 @@ serverConnectionRetryInterval = 30 devicePath = "/dev/remote" # Path to the fifo notifying the motehost of mote hotplug events. -usbPlugEventPipe = "/var/run/motehost.events" +eventPipe = "/var/run/motehost.events" diff --git a/contrib/etc/remote-mcs.cfg b/contrib/etc/remote-mcs.cfg index 1566811..86a790f 100644 --- a/contrib/etc/remote-mcs.cfg +++ b/contrib/etc/remote-mcs.cfg @@ -7,5 +7,5 @@ dbUser = "remote_admin" dbPassword = "remote" # Ports -sessionListenerPort = 10000 -hostListenerPort = 10001 +sessionPort = 10000 +hostPort = 10001 diff --git a/doc/remote-device-add.7 b/doc/remote-device-add.7 index e10f080..038a14f 100644 --- a/doc/remote-device-add.7 +++ b/doc/remote-device-add.7 @@ -1,11 +1,11 @@ .\" Title: remote-device-add .\" Author: .\" Generator: DocBook XSL Stylesheets v1.73.2 -.\" Date: 03/25/2008 +.\" Date: 05/18/2008 .\" Manual: Re-Mote Testbed Framework -.\" Source: remote-mci 1.1.git +.\" Source: remote-mci 2.0.git .\" -.TH "REMOTE\-DEVICE\-ADD" "7" "03/25/2008" "remote\-mci 1\.1\.git" "Re\-Mote Testbed Framework" +.TH "REMOTE\-DEVICE\-ADD" "7" "05/18/2008" "remote\-mci 2\.0\.git" "Re\-Mote Testbed Framework" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) diff --git a/doc/remote-device-name.7 b/doc/remote-device-name.7 index f3e5012..24cd610 100644 --- a/doc/remote-device-name.7 +++ b/doc/remote-device-name.7 @@ -1,11 +1,11 @@ .\" Title: remote-device-name .\" Author: .\" Generator: DocBook XSL Stylesheets v1.73.2 -.\" Date: 03/25/2008 +.\" Date: 05/18/2008 .\" Manual: Re-Mote Testbed Framework -.\" Source: remote-mci 1.1.git +.\" Source: remote-mci 2.0.git .\" -.TH "REMOTE\-DEVICE\-NAME" "7" "03/25/2008" "remote\-mci 1\.1\.git" "Re\-Mote Testbed Framework" +.TH "REMOTE\-DEVICE\-NAME" "7" "05/18/2008" "remote\-mci 2\.0\.git" "Re\-Mote Testbed Framework" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) diff --git a/doc/remote-device-remove.7 b/doc/remote-device-remove.7 index 09a55e2..d22c2db 100644 --- a/doc/remote-device-remove.7 +++ b/doc/remote-device-remove.7 @@ -1,11 +1,11 @@ .\" Title: remote-device-remove .\" Author: .\" Generator: DocBook XSL Stylesheets v1.73.2 -.\" Date: 03/25/2008 +.\" Date: 05/18/2008 .\" Manual: Re-Mote Testbed Framework -.\" Source: remote-mci 1.1.git +.\" Source: remote-mci 2.0.git .\" -.TH "REMOTE\-DEVICE\-REMO" "7" "03/25/2008" "remote\-mci 1\.1\.git" "Re\-Mote Testbed Framework" +.TH "REMOTE\-DEVICE\-REMO" "7" "05/18/2008" "remote\-mci 2\.0\.git" "Re\-Mote Testbed Framework" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) diff --git a/doc/remote-mch.1 b/doc/remote-mch.1 index 1a0d4f8..e385e38 100644 --- a/doc/remote-mch.1 +++ b/doc/remote-mch.1 @@ -1,11 +1,11 @@ .\" Title: remote-mch .\" Author: .\" Generator: DocBook XSL Stylesheets v1.73.2 -.\" Date: 03/25/2008 +.\" Date: 05/18/2008 .\" Manual: Re-Mote Testbed Framework -.\" Source: remote-mci 1.1.git +.\" Source: remote-mci 2.0.git .\" -.TH "REMOTE\-MCH" "1" "03/25/2008" "remote\-mci 1\.1\.git" "Re\-Mote Testbed Framework" +.TH "REMOTE\-MCH" "1" "05/18/2008" "remote\-mci 2\.0\.git" "Re\-Mote Testbed Framework" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) @@ -21,36 +21,38 @@ The mote control host manages mote devices and provides remote access to them th The mote control host may be run both in the foreground and as a daemon\. .sp .SH "OPTIONS" -The following options can be specified on the command line\. +The following options are only usable on the command line\. .PP -\-\-config\-file= +\-\-config= .RS 4 -Path to the configuration file\. Default is "/etc/remote\-mch\.cfg"\. +Path to the configuration file\. Defaults to "/etc/remote\-mch\.cfg"\. .RE .PP -\-\-daemonize=[1|0] +\-\-help .RS 4 -Run as a daemon\. Default is to not daemonize\. +Print usage help and exit\. .RE .PP -\-\-help +\-\-version .RS 4 -Print usage help and exit\. +Print version info and exit\. .RE -.SH "CONFIGURATION OPTIONS" -Use the following options to configure the mote host\. +.SS "Configuration options" +In addition, to the above options the mote host accepts the following configuration options that can be specified either on the command line or in the configuration file\. An option set in the configuration file overrides any option set on the command line\. +.sp +On the command line use: \fI\-\-\fR \fI=\fR , e\.g\. \fI\-\-devicePath=/here\fR\. In the config file use: \fI=\fR , e\.g\. \fIdevicePath=/here\fR\. For boolean options the \fI=\fR and value may be left out to set the value to true\. See the example sections for more information\. .PP devicePath .RS 4 Path to the mote device hierarchy\. When not specified "/dev/remote/" is used\. .RE .PP -usbPlugEventPipe +eventPipe .RS 4 Path to the fifo notifying the mote host of mote hotplug events\. By default the daemon listens on "/var/run/motehost\.events"\. .RE .PP -serverAddress +serverHost .RS 4 DNS or IP address of the mote server\. Default is localhost\. .RE @@ -60,10 +62,15 @@ serverPort Port number to use for connecting to the mote server\. The default port is 10001\. .RE .PP -serverConnectionRetryInterval +retryInterval .RS 4 Number of seconds to wait between server connection retries\. Default is 30 seconds\. .RE +.PP +daemonize +.RS 4 +Whether or not to run in the background as a daemon\. The default is to not run as a daemon\. +.RE .SH "FILES" The mote host uses the following configurable files\. .PP @@ -76,6 +83,7 @@ Default configuration file read on startup\. .RS 4 Default file for listening on mote events\. .RE +.SS "Mote device files" For each mote managed by the mote host, the following device specific files are used\. The device path is configurable (default: "/dev/remote")\. MOTEMAC represents the MAC address of a mote\. .PP /dev/remote/MOTEMAC/programmer @@ -113,7 +121,7 @@ File containing the mote device path in the form of a path specifying the bus ID File containing the name of the mote platform\. E\.g\. "dig528\-2"\. .RE .SH "ENVIRONMENT VARIABLES" -The mote host does not use any externally defined environment variables\. When invoking the programmer and controller commands the mote host uses the following environment variables\. +The mote host does not use any externally defined environment variables\. When invoking the programmer and controller commands the mote host sets the following environment variables\. .PP platform .RS 4 @@ -129,6 +137,33 @@ tosaddress .RS 4 The mote TOS address\. .RE +.SH "EXAMPLES" +.PP +Using configuration options on the command line +.RS 4 +If you only need to override the default values for the server host and port and don\'t want to use a configuration file, specify all option on the command line\. +.sp +.RS 4 +.nf +$ remote\-mch \-\-serverHost=my\.server\.tld \-\-serverPort=10001 \-\-daemonize +.fi +.RE +.RE +.PP +A simple configuration file +.RS 4 +The following configuration file sets the same values as the above example\. +.sp +.RS 4 +.nf +# MCS location +serverHost=my\.server\.tld +serverPort=10001 +# Run in the background +daemonize +.fi +.RE +.RE .SH "COPYRIGHT" .sp .RS 4 diff --git a/doc/remote-mch.1.txt b/doc/remote-mch.1.txt index ff9b8ba..43a8581 100644 --- a/doc/remote-mch.1.txt +++ b/doc/remote-mch.1.txt @@ -21,35 +21,43 @@ The mote control host may be run both in the foreground and as a daemon. OPTIONS ------- -The following options can be specified on the command line. +The following options are only usable on the command line. ---config-file=:: +--config=:: - Path to the configuration file. Default is "/etc/remote-mch.cfg". - ---daemonize=[1|0]:: - - Run as a daemon. Default is to not daemonize. + Path to the configuration file. Defaults to "/etc/remote-mch.cfg". --help:: Print usage help and exit. -CONFIGURATION OPTIONS ---------------------- -Use the following options to configure the mote host. +--version:: + + Print version info and exit. + +Configuration options +~~~~~~~~~~~~~~~~~~~~~ +In addition, to the above options the mote host accepts the following +configuration options that can be specified either on the command line or in +the configuration file. An option set in the configuration file overrides +any option set on the command line. + +On the command line use: '--' '=' , e.g. '--devicePath=/here'. +In the config file use: '=' , e.g. 'devicePath=/here'. For +boolean options the '=' and value may be left out to set the value to true. +See the example sections for more information. devicePath :: Path to the mote device hierarchy. When not specified "/dev/remote/" is used. -usbPlugEventPipe :: +eventPipe :: Path to the fifo notifying the mote host of mote hotplug events. By default the daemon listens on "/var/run/motehost.events". -serverAddress :: +serverHost :: DNS or IP address of the mote server. Default is localhost. @@ -59,11 +67,16 @@ serverPort :: Port number to use for connecting to the mote server. The default port is 10001. -serverConnectionRetryInterval :: +retryInterval :: Number of seconds to wait between server connection retries. Default is 30 seconds. +daemonize :: + + Whether or not to run in the background as a daemon. + The default is to not run as a daemon. + FILES ----- The mote host uses the following configurable files. @@ -76,6 +89,9 @@ The mote host uses the following configurable files. Default file for listening on mote events. +Mote device files +~~~~~~~~~~~~~~~~~ + For each mote managed by the mote host, the following device specific files are used. The device path is configurable (default: "/dev/remote"). MOTEMAC represents the MAC address of a mote. @@ -114,7 +130,7 @@ represents the MAC address of a mote. ENVIRONMENT VARIABLES --------------------- The mote host does not use any externally defined environment variables. When -invoking the programmer and controller commands the mote host uses the +invoking the programmer and controller commands the mote host sets the following environment variables. platform:: @@ -129,6 +145,28 @@ tosaddress:: The mote TOS address. +EXAMPLES +-------- + +Using configuration options on the command line:: + + If you only need to override the default values for the server host + and port and don't want to use a configuration file, specify all + option on the command line. + + $ remote-mch --serverHost=my.server.tld --serverPort=10001 --daemonize + +A simple configuration file:: + + The following configuration file sets the same values as the above + example. + + # MCS location + serverHost=my.server.tld + serverPort=10001 + # Run in the background + daemonize + COPYRIGHT --------- [verse] diff --git a/doc/remote-mcs.1 b/doc/remote-mcs.1 index 8578bd3..a327124 100644 --- a/doc/remote-mcs.1 +++ b/doc/remote-mcs.1 @@ -1,11 +1,11 @@ .\" Title: remote-mcs .\" Author: .\" Generator: DocBook XSL Stylesheets v1.73.2 -.\" Date: 03/25/2008 +.\" Date: 05/18/2008 .\" Manual: Re-Mote Testbed Framework -.\" Source: remote-mci 1.1.git +.\" Source: remote-mci 2.0.git .\" -.TH "REMOTE\-MCS" "1" "03/25/2008" "remote\-mci 1\.1\.git" "Re\-Mote Testbed Framework" +.TH "REMOTE\-MCS" "1" "05/18/2008" "remote\-mci 2\.0\.git" "Re\-Mote Testbed Framework" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) @@ -21,24 +21,26 @@ The mote control server manages connections from mote control hosts and user cli The mote control server may be run both in the foreground and as a daemon\. .sp .SH "OPTIONS" -The following options can be specified on the command line\. +The following options are only usable on the command line\. .PP -\-\-config\-file= +\-\-config= .RS 4 -Path to the configuration file\. Default is "/etc/remote\-mcs\.cfg"\. +Path to the configuration file\. Defaults to "/etc/remote\-mcs\.cfg"\. .RE .PP -\-\-daemonize=[1|0] +\-\-help .RS 4 -Specify whether to run as a daemon\. Default is to not daemonize\. +Print usage help and exit\. .RE .PP -\-\-help +\-\-version .RS 4 -Print usage help and exit\. +Print version info and exit\. .RE -.SH "CONFIGURATION OPTIONS" -Use the following options to configure the mote host\. +.SS "Configuration options" +In addition, to the above options the mote control server accepts the following configuration options that can be specified either on the command line or in the configuration file\. An option set in the configuration file overrides any option set on the command line\. +.sp +On the command line use: \fI\-\-\fR \fI=\fR , e\.g\. \fI\-\-devicePath=/here\fR\. In the config file use: \fI=\fR , e\.g\. \fIdevicePath=/here\fR\. For boolean options the \fI=\fR and value may be left out to set the value to true\. See the example sections for more information\. .PP dbName .RS 4 @@ -60,14 +62,14 @@ dbPassword Password for the infrastructure database\. .RE .PP -sessionListenerPort +sessionPort .RS 4 Port number to use when listening for new sessions\. The default port is 10000\. .RE .PP -hostListenerPort +hostPort .RS 4 -Port number to use when listening for new hosts\. Defaults to port 10001\. +Port number to use when listening for new mote hosts\. Defaults to port 10001\. .RE .PP pidFile @@ -75,15 +77,20 @@ pidFile Path to the file containing the PID of the mote host\. Defaults to "/var/run/remote\-mcs\.pid"\. .RE .PP -log\-file +logFile .RS 4 Path to the output log file when running as a daemon\. MCS will log to "/var/log/remote\-mcs\.log" by default\. .RE .PP -errorlog\-file +errorFile .RS 4 Path to the error log file when running as a daemon\. Errors will be logged to "/var/log/remote\-mcs\-error\.log" by default\. .RE +.PP +daemonize +.RS 4 +Whether or not to run in the background as a daemon\. Defaults to false\. +.RE .SH "FILES" The mote control server uses the following configurable files\. .PP @@ -99,6 +106,34 @@ Default PID file path\. .SH "ENVIRONMENT VARIABLES" The mote control server does not use any environment variables\. .sp +.SH "EXAMPLES" +.PP +Using configuration options on the command line +.RS 4 +If you only need to override the default values for the database access and don\'t want to use a configuration file, specify all option on the command line\. +.sp +.RS 4 +.nf +$ remote\-mcs \-\-dbName=REMOTE \-\-dbUser=remote_admin \-\-dbPassword=123 +.fi +.RE +.RE +.PP +A simple configuration file +.RS 4 +The following configuration file sets the same values as the above example and also tells the mote control server to run as a daemon\. +.sp +.RS 4 +.nf +# Database credentials +dbName=REMOTE +dbUser=remote_admin +dbPassword=123 +# Run in the background +daemonize +.fi +.RE +.RE .SH "COPYRIGHT" .sp .RS 4 diff --git a/doc/remote-mcs.1.txt b/doc/remote-mcs.1.txt index df23c4e..041a0c4 100644 --- a/doc/remote-mcs.1.txt +++ b/doc/remote-mcs.1.txt @@ -22,23 +22,31 @@ The mote control server may be run both in the foreground and as a daemon. OPTIONS ------- -The following options can be specified on the command line. +The following options are only usable on the command line. ---config-file=:: +--config=:: - Path to the configuration file. Default is "/etc/remote-mcs.cfg". - ---daemonize=[1|0]:: - - Specify whether to run as a daemon. Default is to not daemonize. + Path to the configuration file. Defaults to "/etc/remote-mcs.cfg". --help:: Print usage help and exit. -CONFIGURATION OPTIONS ---------------------- -Use the following options to configure the mote host. +--version:: + + Print version info and exit. + +Configuration options +~~~~~~~~~~~~~~~~~~~~~ +In addition, to the above options the mote control server accepts the +following configuration options that can be specified either on the command +line or in the configuration file. An option set in the configuration file +overrides any option set on the command line. + +On the command line use: '--' '=' , e.g. '--devicePath=/here'. +In the config file use: '=' , e.g. 'devicePath=/here'. For +boolean options the '=' and value may be left out to set the value to true. +See the example sections for more information. dbName :: @@ -56,14 +64,14 @@ dbPassword :: Password for the infrastructure database. -sessionListenerPort :: +sessionPort :: Port number to use when listening for new sessions. The default port is 10000. -hostListenerPort :: +hostPort :: - Port number to use when listening for new hosts. + Port number to use when listening for new mote hosts. Defaults to port 10001. pidFile :: @@ -71,17 +79,22 @@ pidFile :: Path to the file containing the PID of the mote host. Defaults to "/var/run/remote-mcs.pid". -log-file :: +logFile :: Path to the output log file when running as a daemon. MCS will log to "/var/log/remote-mcs.log" by default. -errorlog-file :: +errorFile :: Path to the error log file when running as a daemon. Errors will be logged to "/var/log/remote-mcs-error.log" by default. +daemonize :: + + Whether or not to run in the background as a daemon. + Defaults to false. + FILES ----- The mote control server uses the following configurable files. @@ -98,6 +111,29 @@ ENVIRONMENT VARIABLES --------------------- The mote control server does not use any environment variables. +EXAMPLES +-------- + +Using configuration options on the command line:: + + If you only need to override the default values for the database + access and don't want to use a configuration file, specify all + option on the command line. + + $ remote-mcs --dbName=REMOTE --dbUser=remote_admin --dbPassword=123 + +A simple configuration file:: + + The following configuration file sets the same values as the above + example and also tells the mote control server to run as a daemon. + + # Database credentials + dbName=REMOTE + dbUser=remote_admin + dbPassword=123 + # Run in the background + daemonize + COPYRIGHT --------- [verse] diff --git a/libutil/Config.cc b/libutil/Config.cc new file mode 100644 index 0000000..ab75fa9 --- /dev/null +++ b/libutil/Config.cc @@ -0,0 +1,310 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include +#include "libutil/Config.h" + +namespace remote { namespace util { + +using namespace remote::util; + +class Config::Option +{ +public: + std::string name; + std::string help; + Config::type type; + bool changed; + union { + std::string *string; + uint16_t *uint16; + uint64_t *uint64; + bool *boolean; + Option *alias; + } value; + + Option(std::string name, std::string help, Config::type type) + : name(name), help(help), type(type), changed(false) + { } +}; + +Config::Config(std::string program, std::string configFile) + : program(program), configFile(configFile), options() +{ } + +void Config::operator()(std::string name, bool *boolean, std::string help) +{ + add(name, help, Config::BOOL)->value.boolean = boolean; +} + +void Config::operator()(std::string name, uint16_t *uint16, std::string help) +{ + add(name, help, Config::UINT16)->value.uint16 = uint16; +} + +void Config::operator()(std::string name, uint64_t *uint64, std::string help) +{ + add(name, help, Config::UINT64)->value.uint64 = uint64; +} + +void Config::operator()(std::string name, std::string *string, std::string help) +{ + add(name, help, Config::STRING)->value.string = string; +} + +void Config::operator()(std::string name, std::string alias) +{ + Option *option = get(alias); + + if (!option) + fprintf(stderr, "Option '%s' does not exist\n", name.c_str()); + else + add(name, option->help, Config::ALIAS)->value.alias = option; +} + +bool Config::read(int argc, char **argv) +{ + Option *config = add("config", "Path to config file", Config::STRING); + + add("config-file", "", Config::ALIAS)->value.alias = config; + config->value.string = &configFile; + + add("help", "Print usage and exit", Config::HELP); + add("version", "Print version and exit", Config::VERSION); + + for (int i = 1; i < argc; i++) { + char *arg = argv[i]; + char *sep = strchr(arg, '='); + std::string name; + std::string value = sep ? sep + 1 : ""; + + if (sep) + *sep = 0; + name = arg + strspn(arg, "-"); + if (arg == name) { + fprintf(stderr, "%s is not an option\n", arg); + return false; + } + + if (!parseOption(name, value)) { + fprintf(stderr, "Unknown option %s\n", arg); + return false; + } + } + + if (!parseFile(configFile, config->changed)) + return false; + + return true; +} + +static inline char * +sanitize(char *pos) +{ + int len; + + while (isspace(*pos)) + pos++; + for (len = strlen(pos); len > 0; len--) { + if (!isspace(pos[len - 1])) + break; + pos[len - 1] = 0; + } + + return pos; +} + +bool Config::parseFile(std::string path, bool fail) +{ + FILE *file = fopen(path.c_str(), "r"); + char buf[BUFSIZ]; + size_t lineno; + + if (!file) { + if (!fail) + return true; + fprintf(stderr, "Failed to open %s: %s\n", + path.c_str(), strerror(errno)); + return false; + } + + for (lineno = 0; fgets(buf, sizeof(buf), file); lineno++) { + char *pos = strchr(buf, '#'); + std::string name, value; + + if (pos) + *pos = 0; + + pos = strchr(buf, '='); + if (pos) { + *pos++ = 0; + value = sanitize(pos); + } + name = sanitize(buf); + + if (name == "") { + if (value != "") + fprintf(stderr, "Garbage on line %d\n", lineno); + continue; + } + + if (!parseOption(name, value)) { + fprintf(stderr, "File %s line %d: Unknown option %s\n", + path.c_str(), lineno, name.c_str()); + return false; + } + } + fclose(file); + return true; +} + +Config::Option *Config::get(std::string name) +{ + std::list