Allow building WITHOUT_STATS
[freeradius.git] / src / main / radiusd.c
index 06b26da..20ad58e 100644 (file)
@@ -29,7 +29,6 @@
 RCSID("$Id$")
 
 #include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/radius_snmp.h>
 #include <freeradius-devel/modules.h>
 #include <freeradius-devel/rad_assert.h>
 
@@ -54,11 +53,6 @@ RCSID("$Id$")
 #      define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
 #endif
 
-#ifndef HAVE_PTHREAD_H
-#define thread_pool_lock(_x)
-#define thread_pool_unlock(_x)
-#endif
-
 /*
  *  Global variables.
  */
@@ -73,7 +67,6 @@ int check_config = FALSE;
 
 const char *radiusd_version = "FreeRADIUS Version " RADIUSD_VERSION ", for host " HOSTINFO ", built on " __DATE__ " at " __TIME__;
 
-time_t time_now;
 pid_t radius_pid;
 
 static int debug_memory = 0;
@@ -136,7 +129,7 @@ int main(int argc, char *argv[])
        memset(&mainconfig, 0, sizeof(mainconfig));
        mainconfig.myip.af = AF_UNSPEC;
        mainconfig.port = -1;
-       mainconfig.name = progname;
+       mainconfig.name = "radiusd";
 
 #ifdef HAVE_SIGACTION
        memset(&act, 0, sizeof(act));
@@ -148,11 +141,12 @@ int main(int argc, char *argv[])
         *      Don't put output anywhere until we get told a little
         *      more.
         */
+       mainconfig.radlog_dest = RADLOG_NULL;
        mainconfig.radlog_fd = -1;
        mainconfig.log_file = NULL;
 
        /*  Process the options.  */
-       while ((argval = getopt(argc, argv, "Cd:fhi:mn:p:svxX")) != EOF) {
+       while ((argval = getopt(argc, argv, "Cd:fhi:l:mn:p:stvxX")) != EOF) {
 
                switch(argval) {
                        case 'C':
@@ -174,6 +168,20 @@ int main(int argc, char *argv[])
                                usage(0);
                                break;
 
+                       case 'l':
+                               if (strcmp(optarg, "stdout") == 0) {
+                                       goto do_stdout;
+                               }
+                               mainconfig.log_file = strdup(optarg);
+                               mainconfig.radlog_dest = RADLOG_FILES;
+                               mainconfig.radlog_fd = open(mainconfig.log_file,
+                                                           O_WRONLY | O_APPEND | O_CREAT, 0640);
+                               if (mainconfig.radlog_fd < 0) {
+                                       fprintf(stderr, "radiusd: Failed to open log file %s: %s\n", mainconfig.log_file, strerror(errno));
+                                       exit(1);
+                               }
+                               break;            
+
                        case 'i':
                                if (ip_hton(optarg, AF_UNSPEC, &mainconfig.myip) < 0) {
                                        fprintf(stderr, "radiusd: Invalid IP Address or hostname \"%s\"\n", optarg);
@@ -205,6 +213,10 @@ int main(int argc, char *argv[])
                                dont_fork = TRUE;
                                break;
 
+                       case 't':       /* no child threads */
+                               spawn_flag = FALSE;
+                               break;
+
                        case 'v':
                                version();
                                break;
@@ -216,8 +228,10 @@ int main(int argc, char *argv[])
                                mainconfig.log_auth = TRUE;
                                mainconfig.log_auth_badpass = TRUE;
                                mainconfig.log_auth_goodpass = TRUE;
+               do_stdout:
                                mainconfig.radlog_dest = RADLOG_STDOUT;
                                mainconfig.radlog_fd = STDOUT_FILENO;
+                               fr_log_fp = stdout;
                                break;
 
                        case 'x':
@@ -237,11 +251,11 @@ int main(int argc, char *argv[])
 
        if (debug_flag) {
                radlog(L_INFO, "%s", radiusd_version);
-               radlog(L_INFO, "Copyright (C) 2000-2007 The FreeRADIUS server project.\n");
+               radlog(L_INFO, "Copyright (C) 1999-2009 The FreeRADIUS server project and contributors.\n");
                radlog(L_INFO, "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n");
                radlog(L_INFO, "PARTICULAR PURPOSE.\n");
                radlog(L_INFO, "You may redistribute copies of FreeRADIUS under the terms of the\n");
-               radlog(L_INFO, "GNU General Public License.\n");
+               radlog(L_INFO, "GNU General Public License v2.\n");
                fflush(NULL);
        }
 
@@ -254,7 +268,7 @@ int main(int argc, char *argv[])
        /*
         *  Disconnect from session
         */
-       if (debug_flag == 0 && dont_fork == FALSE) {
+       if (dont_fork == FALSE) {
                pid_t pid = fork();
 
                if (pid < 0) {
@@ -281,30 +295,6 @@ int main(int argc, char *argv[])
        radius_pid = getpid();
 
        /*
-        *  Only write the PID file if we're running as a daemon.
-        *
-        *  And write it AFTER we've forked, so that we write the
-        *  correct PID.
-        */
-       if (dont_fork == FALSE) {
-               FILE *fp;
-
-               fp = fopen(mainconfig.pid_file, "w");
-               if (fp != NULL) {
-                       /*
-                        *      FIXME: What about following symlinks,
-                        *      and having it over-write a normal file?
-                        */
-                       fprintf(fp, "%d\n", (int) radius_pid);
-                       fclose(fp);
-               } else {
-                       radlog(L_ERR|L_CONS, "Failed creating PID file %s: %s\n",
-                              mainconfig.pid_file, strerror(errno));
-                       exit(1);
-               }
-       }
-
-       /*
         *      If we're running as a daemon, close the default file
         *      descriptors, AFTER forking.
         */
@@ -320,10 +310,12 @@ int main(int argc, char *argv[])
                dup2(devnull, STDIN_FILENO);
                if (mainconfig.radlog_dest == RADLOG_STDOUT) {
                        mainconfig.radlog_fd = dup(STDOUT_FILENO);
+                       setlinebuf(stdout);
                }
                dup2(devnull, STDOUT_FILENO);
                if (mainconfig.radlog_dest == RADLOG_STDERR) {
                        mainconfig.radlog_fd = dup(STDERR_FILENO);
+                       setlinebuf(stdout);
                }
                dup2(devnull, STDERR_FILENO);
                close(devnull);
@@ -333,8 +325,7 @@ int main(int argc, char *argv[])
        }
 
        /*
-        *      It's called the thread pool, but it does a little
-        *      more than that.
+        *      Initialize the event pool, including threads.
         */
        radius_event_init(mainconfig.config, spawn_flag);
 
@@ -379,18 +370,47 @@ int main(int argc, char *argv[])
         *      Everything seems to have loaded OK, exit gracefully.
         */
        if (check_config) {
-               DEBUG("Configuration appears OK.");
+               DEBUG("Configuration appears to be OK.");
                exit(0);
        }
 
+#ifdef WITH_STATS
+       radius_stats_init(0);
+#endif
+
+       /*
+        *  Only write the PID file if we're running as a daemon.
+        *
+        *  And write it AFTER we've forked, so that we write the
+        *  correct PID.
+        */
+       if (dont_fork == FALSE) {
+               FILE *fp;
+
+               fp = fopen(mainconfig.pid_file, "w");
+               if (fp != NULL) {
+                       /*
+                        *      FIXME: What about following symlinks,
+                        *      and having it over-write a normal file?
+                        */
+                       fprintf(fp, "%d\n", (int) radius_pid);
+                       fclose(fp);
+               } else {
+                       radlog(L_ERR|L_CONS, "Failed creating PID file %s: %s\n",
+                              mainconfig.pid_file, strerror(errno));
+                       exit(1);
+               }
+       }
+
        /*
         *      Process requests until HUP or exit.
         */
        while ((rcode = radius_event_process()) == 0x80) {
-               module_hup(cf_section_sub_find(mainconfig.config, "modules"));
+               radius_stats_init(1);
+               hup_mainconfig();
        }
        
-       DEBUG("Exiting...");
+       radlog(L_INFO, "Exiting normally.");
        
        /*
         *      Ignore the TERM signal: we're
@@ -405,7 +425,7 @@ int main(int argc, char *argv[])
         *      ignored.)
         */
 #ifndef __MINGW32__
-       kill(-radius_pid, SIGTERM);
+       if (spawn_flag) kill(-radius_pid, SIGTERM);
 #endif
        
        /*
@@ -472,13 +492,6 @@ static void NEVER_RETURNS usage(int status)
 static void sig_fatal(int sig)
 {
        switch(sig) {
-               case SIGSEGV:
-                       /*
-                        *      We can't really do anything
-                        *      intelligent here so just die
-                        */
-                       _exit(1);
-
                case SIGTERM:
                        radius_signal_self(RADIUS_SIGNAL_SELF_TERM);
                        break;
@@ -494,8 +507,7 @@ static void sig_fatal(int sig)
                        /* FALL-THROUGH */
 
                default:
-                       radius_signal_self(RADIUS_SIGNAL_SELF_EXIT);
-                       break;
+                       _exit(sig);
        }
 }