Add release codename.
[umurmur.git] / src / main.c
index cef4f605a4d2e88877d7e488dbb83302e378f962..215049fedc08c1a16f4d81166389de9598d9d6ec 100644 (file)
@@ -1,5 +1,5 @@
-/* Copyright (C) 2009-2010, Martin Johansson <martin@fatbob.nu>
-   Copyright (C) 2005-2010, Thorvald Natvig <thorvald@natvig.com>
+/* Copyright (C) 2009-2012, Martin Johansson <martin@fatbob.nu>
+   Copyright (C) 2005-2012, Thorvald Natvig <thorvald@natvig.com>
 
    All rights reserved.
 
@@ -29,7 +29,6 @@
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-
 #include <stdio.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <string.h>
 #include <stdlib.h>
 #ifdef _POSIX_PRIORITY_SCHEDULING
+#if (_POSIX_PRIORITY_SCHEDULING > 0)
+#define POSIX_PRIORITY_SCHEDULING
 #include <sched.h>
 #endif
+#endif
 #include "server.h"
 #include "ssl.h"
 #include "channel.h"
@@ -163,8 +165,8 @@ void signal_handler(int sig)
 {
        switch(sig) {
        case SIGHUP:
-               /* XXX - do stuff? */
-               Log_info("HUP signal");
+               Log_info("HUP signal received.");
+               Log_reset();
                break;
        case SIGTERM:
                Log_info("TERM signal. Shutting down.");
@@ -201,7 +203,7 @@ void daemonize()
                
 }
 
-#ifdef _POSIX_PRIORITY_SCHEDULING
+#ifdef POSIX_PRIORITY_SCHEDULING
 void setscheduler()
 {
        int rc;
@@ -217,14 +219,16 @@ void setscheduler()
 
 void printhelp()
 {
-       printf("uMurmur version %s. Mumble protocol %d.%d.%d\n", UMURMUR_VERSION, PROTVER_MAJOR, PROTVER_MINOR, PROTVER_PATCH);
-       printf("Usage: umurmurd [-d] [-p <pidfile>] [-c <conf file>] [-h]\n");
-       printf("       -d             - Do not daemonize\n");
-       printf("       -p <pidfile>   - Write PID to this file\n");
-       printf("       -c <conf file> - Specify configuration file\n");
-#ifdef _POSIX_PRIORITY_SCHEDULING
+       printf("uMurmur version %s ('%s'). Mumble protocol %d.%d.%d\n", UMURMUR_VERSION,
+              UMURMUR_CODENAME, PROTVER_MAJOR, PROTVER_MINOR, PROTVER_PATCH);
+       printf("Usage: umurmurd [-d] [-r] [-h] [-p <pidfile>] [-t] [-c <conf file>] [-a <addr>] [-b <port>]\n");
+       printf("       -d             - Do not daemonize - run in foreground.\n");
+#ifdef POSIX_PRIORITY_SCHEDULING
        printf("       -r             - Run with realtime priority\n");
 #endif
+       printf("       -p <pidfile>   - Write PID to this file\n");
+       printf("       -c <conf file> - Specify configuration file (default %s)\n", DEFAULT_CONFIG);
+       printf("       -t             - Test config. Error message to stderr + non-zero exit code on error\n");
        printf("       -a <address>   - Bind to IP address\n");
        printf("       -b <port>      - Bind to port\n");
        printf("       -h             - Print this help\n");
@@ -234,18 +238,19 @@ void printhelp()
 int main(int argc, char **argv)
 {
        bool_t nodaemon = false;
-#ifdef _POSIX_PRIORITY_SCHEDULING
+#ifdef POSIX_PRIORITY_SCHEDULING
        bool_t realtime = false;
 #endif
+       bool_t testconfig = false;
        char *conffile = NULL, *pidfile = NULL;
        int c;
        struct utsname utsbuf;
        
        /* Arguments */
-#ifdef _POSIX_PRIORITY_SCHEDULING
-       while ((c = getopt(argc, argv, "drp:c:a:b:h")) != EOF) {
+#ifdef POSIX_PRIORITY_SCHEDULING
+       while ((c = getopt(argc, argv, "drp:c:a:b:ht")) != EOF) {
 #else
-       while ((c = getopt(argc, argv, "dp:c:a:b:h")) != EOF) {
+       while ((c = getopt(argc, argv, "dp:c:a:b:ht")) != EOF) {
 #endif
                switch(c) {
                case 'c':
@@ -266,7 +271,10 @@ int main(int argc, char **argv)
                case 'h':
                        printhelp();
                        break;
-#ifdef _POSIX_PRIORITY_SCHEDULING
+               case 't':
+                       testconfig = true;
+                       break;
+#ifdef POSIX_PRIORITY_SCHEDULING
                case 'r':
                        realtime = true;
                        break;
@@ -278,27 +286,35 @@ int main(int argc, char **argv)
                }
        }
 
-       /* Logging to terminal if not daemonizing, otherwise to syslog.
-        * Need to initialize logging before calling Conf_init()
-        */
-       if (!nodaemon)
-               Log_init(false);
-       else
-               Log_init(true);
-       
+       if (testconfig) {
+               if (!Conf_ok(conffile))
+                       exit(1);
+               else
+                       exit(0);
+       }
+               
        /* Initialize the config subsystem early;
-        * switch_user() will need to read some config variables.
+        * switch_user() will need to read some config variables as well as logging.
         */
        Conf_init(conffile);
-
+       
+       /* Logging to terminal if not daemonizing, otherwise to syslog or log file.
+        */
        if (!nodaemon) {
                daemonize();
+               Log_init(false);
                if (pidfile != NULL)
                        lockfile(pidfile);
 
                switch_user();
-       }
 
+               /* Reopen log file. If user switch results in access denied, we catch
+                * it early.
+                */
+               Log_reset(); 
+       }
+       else Log_init(true);
+       
        signal(SIGCHLD, SIG_IGN); /* ignore child */
        signal(SIGTSTP, SIG_IGN); /* ignore tty signals */
        signal(SIGTTOU, SIG_IGN);
@@ -321,14 +337,16 @@ int main(int argc, char **argv)
        SSLi_init();
        Chan_init();
        Client_init();
+       Ban_init();
 
-#ifdef _POSIX_PRIORITY_SCHEDULING
+#ifdef POSIX_PRIORITY_SCHEDULING
        if (realtime)
                setscheduler();
 #endif
        
        Server_run();
        
+       Ban_deinit();
        SSLi_deinit();
        Chan_free();
        Log_free();