Remove support for deprecated command-line options
[freeradius.git] / src / main / radiusd.c
index 141eb2a..47be608 100644 (file)
@@ -30,6 +30,7 @@ RCSID("$Id$")
 
 #include <freeradius-devel/radiusd.h>
 #include <freeradius-devel/radius_snmp.h>
+#include <freeradius-devel/modules.h>
 #include <freeradius-devel/rad_assert.h>
 
 #include <sys/file.h>
@@ -53,6 +54,11 @@ 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.
  */
@@ -63,7 +69,7 @@ const char *radlog_dir = NULL;
 const char *radlib_dir = NULL;
 int log_stripped_names;
 int debug_flag = 0;
-int log_auth_detail = FALSE;
+int check_config = FALSE;
 
 const char *radiusd_version = "FreeRADIUS Version " RADIUSD_VERSION ", for host " HOSTINFO ", built on " __DATE__ " at " __TIME__;
 
@@ -82,23 +88,24 @@ static int debug_memory = 0;
 static void usage(int);
 
 static void sig_fatal (int);
+#ifdef SIGHUP
 static void sig_hup (int);
+#endif
 
 /*
  *     The main guy.
  */
 int main(int argc, char *argv[])
 {
-       unsigned char buffer[4096];
+       int rcode;
        int argval;
-       pid_t pid;
        int spawn_flag = TRUE;
        int dont_fork = FALSE;
+       int flag = 0;
 
 #ifdef HAVE_SIGACTION
        struct sigaction act;
 #endif
-       rad_listen_t *listener;
 
 #ifdef OSFC2
        set_auth_parameters(argc,argv);
@@ -109,6 +116,16 @@ int main(int argc, char *argv[])
        else
                progname++;
 
+#ifdef WIN32
+       {
+               WSADATA wsaData;
+               if (WSAStartup(MAKEWORD(2, 0), &wsaData)) {
+                       fprintf(stderr, "%s: Unable to initialize socket library.\n");
+                       return 1;
+               }
+       }
+#endif
+
        debug_flag = 0;
        spawn_flag = TRUE;
        radius_dir = strdup(RADIUS_DIR);
@@ -135,21 +152,13 @@ int main(int argc, char *argv[])
        mainconfig.log_file = NULL;
 
        /*  Process the options.  */
-       while ((argval = getopt(argc, argv, "Aa:bcd:fg:hi:l:mn:p:sSvxXyz")) != EOF) {
+       while ((argval = getopt(argc, argv, "Cd:fhi:mn:p:svxX")) != EOF) {
 
                switch(argval) {
-
-                       case 'A':
-                               log_auth_detail = TRUE;
-                               break;
-
-                       case 'a':
-                               if (radacct_dir) free(radacct_dir);
-                               radacct_dir = strdup(optarg);
-                               break;
-
-                       case 'c':
-                               /* ignore for backwards compatibility with Cistron */
+                       case 'C':
+                               check_config = TRUE;
+                               spawn_flag = FALSE;
+                               dont_fork = TRUE;
                                break;
 
                        case 'd':
@@ -170,44 +179,13 @@ int main(int argc, char *argv[])
                                        fprintf(stderr, "radiusd: Invalid IP Address or hostname \"%s\"\n", optarg);
                                        exit(1);
                                }
-                               break;
-
-                       case 'l':
-                               if ((strcmp(optarg, "stdout") == 0) ||
-                                   (strcmp(optarg, "stderr") == 0) ||
-                                   (strcmp(optarg, "syslog") == 0)) {
-                                       fprintf(stderr, "radiusd: -l %s is unsupported.  Use log_destination in radiusd.conf\n", optarg);
-                                       exit(1);
-                               }
-                               if (radlog_dir) free(radlog_dir);
-                               radlog_dir = strdup(optarg);
-                               break;
-
-                       case 'g':
-                               fprintf(stderr, "radiusd: -g is unsupported.  Use log_destination in radiusd.conf.\n");
-                               exit(1);
+                               flag |= 1;
                                break;
 
                        case 'm':
                                debug_memory = 1;
                                break;
 
-                       case 'n':
-                               if ((strchr(optarg, '/') != NULL) ||
-                                   (strchr(optarg, '.') != NULL) ||
-                                   (strlen(optarg) > 45)) usage(1);
-
-                               snprintf(buffer, sizeof(buffer), "%s.conf",
-                                        optarg);
-                               if (mainconfig.radiusd_conf)
-                                       free(mainconfig.radiusd_conf);
-                               mainconfig.radiusd_conf = strdup(buffer);
-                               break;
-
-                       case 'S':
-                               log_stripped_names++;
-                               break;
-
                        case 'p':
                                mainconfig.port = atoi(optarg);
                                if ((mainconfig.port <= 0) ||
@@ -215,6 +193,7 @@ int main(int argc, char *argv[])
                                        fprintf(stderr, "radiusd: Invalid port number %s\n", optarg);
                                        exit(1);
                                }
+                               flag |= 2;
                                break;
 
                        case 's':       /* Single process mode */
@@ -226,10 +205,6 @@ int main(int argc, char *argv[])
                                version();
                                break;
 
-                               /*
-                                *  BIG debugging mode for users who are
-                                *  TOO LAZY to type '-sfxxyz -l stdout' themselves.
-                                */
                        case 'X':
                                spawn_flag = FALSE;
                                dont_fork = TRUE;
@@ -245,22 +220,17 @@ int main(int argc, char *argv[])
                                debug_flag++;
                                break;
 
-                       case 'y':
-                               mainconfig.log_auth = TRUE;
-                               mainconfig.log_auth_badpass = TRUE;
-                               break;
-
-                       case 'z':
-                               mainconfig.log_auth_badpass = TRUE;
-                               mainconfig.log_auth_goodpass = TRUE;
-                               break;
-
                        default:
                                usage(1);
                                break;
                }
        }
 
+       if (flag && (flag != 0x03)) {
+               fprintf(stderr, "radiusd: The options -i and -p cannot be used individually.\n");
+               exit(1);
+       }
+
        if (debug_flag) {
                radlog(L_INFO, "%s", radiusd_version);
                radlog(L_INFO, "Copyright (C) 2000-2007 The FreeRADIUS server project.\n");
@@ -276,13 +246,15 @@ int main(int argc, char *argv[])
                exit(1);
        }
 
+#ifndef __MINGW32__
        /*
         *  Disconnect from session
         */
        if (debug_flag == 0 && dont_fork == FALSE) {
-               pid = fork();
-               if(pid < 0) {
-                       radlog(L_ERR|L_CONS, "Couldn't fork");
+               pid_t pid = fork();
+
+               if (pid < 0) {
+                       radlog(L_ERR, "Couldn't fork: %s", strerror(errno));
                        exit(1);
                }
 
@@ -296,24 +268,7 @@ int main(int argc, char *argv[])
                setsid();
 #endif
        }
-
-       /*
-        *      If we're NOT debugging, trap fatal signals, so we can
-        *      easily clean up after ourselves.
-        *
-        *      If we ARE debugging, don't trap them, so we can
-        *      dump core.
-        */
-       if ((mainconfig.allow_core_dumps == FALSE) && (debug_flag == 0)) {
-#ifdef SIGSEGV
-#ifdef HAVE_SIGACTION
-               act.sa_handler = sig_fatal;
-               sigaction(SIGSEGV, &act, NULL);
-#else
-               signal(SIGSEGV, sig_fatal);
 #endif
-#endif
-       }
 
        /*
         *  Ensure that we're using the CORRECT pid after forking,
@@ -368,6 +323,9 @@ int main(int argc, char *argv[])
                }
                dup2(devnull, STDERR_FILENO);
                close(devnull);
+
+       } else {
+               setlinebuf(stdout); /* unbuffered output */
        }
 
        /*
@@ -377,47 +335,22 @@ int main(int argc, char *argv[])
        radius_event_init(mainconfig.config, spawn_flag);
 
        /*
-        *  Use linebuffered or unbuffered stdout if
-        *  the debug flag is on.
-        */
-       if (debug_flag == TRUE)
-               setlinebuf(stdout);
-
-       /*
-        *      Print out which ports we're listening on.
-        */
-       for (listener = mainconfig.listen;
-            listener != NULL;
-            listener = listener->next) {
-               listener->print(listener, buffer, sizeof(buffer));
-               switch (listener->type) {
-               case RAD_LISTEN_DETAIL:
-                       break;
-
-               case RAD_LISTEN_SNMP:
-                       DEBUG("Listening on SNMP %s", buffer);
-                       break;
-
-               default:
-                       break;
-               }
-
-               DEBUG("Listening on %s", buffer);
-       }
-
-       /*
         *      Now that we've set everything up, we can install the signal
         *      handlers.  Before this, if we get any signal, we don't know
         *      what to do, so we might as well do the default, and die.
         */
+#ifdef SIGPIPE
        signal(SIGPIPE, SIG_IGN);
+#endif
 #ifdef HAVE_SIGACTION
        act.sa_handler = sig_hup;
        sigaction(SIGHUP, &act, NULL);
        act.sa_handler = sig_fatal;
        sigaction(SIGTERM, &act, NULL);
 #else
+#ifdef SIGHUP
        signal(SIGHUP, sig_hup);
+#endif
        signal(SIGTERM, sig_fatal);
 #endif
        /*
@@ -432,11 +365,44 @@ int main(int argc, char *argv[])
                sigaction(SIGQUIT, &act, NULL);
 #else
                signal(SIGINT, sig_fatal);
+#ifdef SIGQUIT
                signal(SIGQUIT, sig_fatal);
 #endif
+#endif
        }
 
-       radius_event_process();
+       /*
+        *      Everything seems to have loaded OK, exit gracefully.
+        */
+       if (check_config) {
+               DEBUG("Configuration appears OK.");
+               exit(0);
+       }
+
+       /*
+        *      Process requests until HUP or exit.
+        */
+       while ((rcode = radius_event_process()) == 0x80) {
+               module_hup(cf_section_sub_find(mainconfig.config, "modules"));
+       }
+       
+       DEBUG("Exiting...");
+       
+       /*
+        *      Ignore the TERM signal: we're
+        *      about to die.
+        */
+       signal(SIGTERM, SIG_IGN);
+       
+       /*
+        *      Send a TERM signal to all
+        *      associated processes
+        *      (including us, which gets
+        *      ignored.)
+        */
+#ifndef __MINGW32__
+       kill(-radius_pid, SIGTERM);
+#endif
        
        /*
         *      We're exiting, so we can delete the PID
@@ -459,11 +425,15 @@ int main(int argc, char *argv[])
         */
        detach_modules();
        
+       xlat_free();            /* modules may have xlat's */
+
        free(radius_dir);
                
-       if (radius_pid < 0) return 1;
+#ifdef WIN32
+       WSACleanup();
+#endif
 
-       return 0;
+       return (rcode - 1);
 }
 
 
@@ -475,23 +445,18 @@ static void NEVER_RETURNS usage(int status)
        FILE *output = status?stderr:stdout;
 
        fprintf(output,
-                       "Usage: %s [-a acct_dir] [-d db_dir] [-l log_dir] [-i address] [-AcfnsSvXxyz]\n", progname);
+                       "Usage: %s [-d db_dir] [-l log_dir] [-i address] [-fsvXx]\n", progname);
        fprintf(output, "Options:\n\n");
-       fprintf(output, "  -a acct_dir     use accounting directory 'acct_dir'.\n");
-       fprintf(output, "  -A              Log auth detail.\n");
+       fprintf(output, "  -C              Check configuration and exit.\n");
        fprintf(output, "  -d raddb_dir    Configuration files are in \"raddbdir/*\".\n");
        fprintf(output, "  -f              Run as a foreground process, not a daemon.\n");
        fprintf(output, "  -h              Print this help message.\n");
        fprintf(output, "  -i ipaddr       Listen on ipaddr ONLY\n");
-       fprintf(output, "  -l log_dir      Log file is \"log_dir/radius.log\" (not used in debug mode)\n");
        fprintf(output, "  -p port         Listen on port ONLY\n");
        fprintf(output, "  -s              Do not spawn child processes to handle requests.\n");
-       fprintf(output, "  -S              Log stripped names.\n");
        fprintf(output, "  -v              Print server version information.\n");
        fprintf(output, "  -X              Turn on full debugging.\n");
        fprintf(output, "  -x              Turn on additional debugging. (-xx gives more debugging).\n");
-       fprintf(output, "  -y              Log authentication failures, with password.\n");
-       fprintf(output, "  -z              Log authentication successes, with password.\n");
        exit(status);
 }
 
@@ -514,7 +479,9 @@ static void sig_fatal(int sig)
                        break;
 
                case SIGINT:
+#ifdef SIGQUIT
                case SIGQUIT:
+#endif
                        if (debug_memory) {
                                radius_signal_self(RADIUS_SIGNAL_SELF_TERM);
                                break;
@@ -527,7 +494,7 @@ static void sig_fatal(int sig)
        }
 }
 
-
+#ifdef SIGHUP
 /*
  *  We got the hangup signal.
  *  Re-read the configuration files.
@@ -538,7 +505,6 @@ static void sig_hup(int sig)
 
        reset_signal(SIGHUP, sig_hup);
 
-       write(STDOUT_FILENO, "STUFF\n", 6);
-
        radius_signal_self(RADIUS_SIGNAL_SELF_HUP);
 }
+#endif