diff freeDiameter/main.c @ 8:3e143f047f78

Backup for the week-end
author Sebastien Decugis <sdecugis@nict.go.jp>
date Fri, 18 Sep 2009 18:54:07 +0900
parents ef303f1078ab
children fc7c18867cf7
line wrap: on
line diff
--- a/freeDiameter/main.c	Fri Sep 04 18:05:25 2009 +0900
+++ b/freeDiameter/main.c	Fri Sep 18 18:54:07 2009 +0900
@@ -35,22 +35,218 @@
 
 #include "fD.h"
 
+#include <signal.h>
+#include <getopt.h>
+
+
+/* Display package version */
+static void main_version_core(void)
+{
+	printf("%s, version %d.%d.%d"
+#ifdef HG_VERSION
+		" (r%s"
+# ifdef PACKAGE_HG_REVISION
+		"/%s"
+# endif /* PACKAGE_HG_VERSION */
+		")"
+#endif /* HG_VERSION */
+		"\n", 
+		FD_PROJECT_NAME, FD_PROJECT_VERSION_MAJOR, FD_PROJECT_VERSION_MINOR, FD_PROJECT_VERSION_REV
+#ifdef HG_VERSION
+		, HG_VERSION
+# ifdef PACKAGE_HG_REVISION
+		, PACKAGE_HG_REVISION
+# endif /* PACKAGE_HG_VERSION */
+#endif /* HG_VERSION */
+		);
+}
+
+/* Display package version and general info */
+static void main_version(void)
+{
+	main_version_core();
+	printf( "%s\n", FD_PROJECT_COPYRIGHT);
+	printf( "\nSee " FD_PROJECT_NAME " homepage at http://aaa.koganei.wide.ad.jp/\n"
+		" for information, updates and bug reports on this software.\n");
+}
+
+/* Print command-line options */
+static void main_help( void )
+{
+	main_version_core();
+	printf(	"  This daemon is an implementation of the Diameter protocol\n"
+		"  used for Authentication, Authorization, and Accounting (AAA).\n");
+	printf("\nUsage:  " FD_PROJECT_BINARY " [OPTIONS]...\n");
+	printf( "  -h, --help             Print help and exit\n"
+  		"  -V, --version          Print version and exit\n"
+  		"  -c, --config=filename  Read configuration from this file instead of the \n"
+		"                           default location (%s).\n", DEFAULT_CONF_FILE);
+ 	printf( "\nDebug:\n"
+  		"  These options are mostly useful for developers\n"
+  		"  -d, --debug            Increase verbosity of debug messages\n"
+  		"  -q, --quiet            Decrease verbosity then remove debug messages\n");
+}
+
+/* Parse the command-line */
+static int main_cmdline(int argc, char *argv[])
+{
+	int c;
+	int option_index = 0;
+	
+      	struct option long_options[] = {
+		{ "help",	0, NULL, 'h' },
+		{ "version",	0, NULL, 'V' },
+		{ "config",	1, NULL, 'c' },
+		{ "debug",	0, NULL, 'd' },
+		{ "quiet",	0, NULL, 'q' },
+		{ NULL,	0, NULL, 0 }
+	};
+	
+	TRACE_ENTRY("%d %p", argc, argv);
+	
+	/* Loop on arguments */
+	while (1) {
+		c = getopt_long (argc, argv, "hVc:dq", long_options, &option_index);
+		if (c == -1) 
+			break;	/* Exit from the loop.  */
+		
+		switch (c) {
+			case 'h':	/* Print help and exit.  */
+				main_help();
+				exit(0);
+
+			case 'V':	/* Print version and exit.  */
+				main_version();
+				exit(0);
+
+			case 'c':	/* Read configuration from this file instead of the default location..  */
+				CHECK_PARAMS( optarg );
+				fd_g_config->conf_file = optarg;
+				break;
+
+			case 'd':	/* Increase verbosity of debug messages.  */
+				fd_g_debug_lvl++;
+				break;
+				
+			case 'q':	/* Decrease verbosity then remove debug messages.  */
+				fd_g_debug_lvl--;
+				break;
+
+			case '?':	/* Invalid option.  */
+				/* `getopt_long' already printed an error message.  */
+				TRACE_DEBUG(INFO, "getopt_long found an invalid character\n");
+				return EINVAL;
+
+			default:	/* bug: option not considered.  */
+				TRACE_DEBUG(INFO, "A command-line option is missing in parser: %c\n", c);
+				ASSERT(0);
+				return EINVAL;
+		}
+	}
+		
+	return 0;
+	
+}
+
+#ifdef HAVE_SIGNALENT_H
+const char *const signalstr[] = {
+# include "signalent.h"
+};
+const int nsignalstr = sizeof signalstr / sizeof signalstr[0];
+# define SIGNALSTR(sig) (((sig) < nsignalstr) ? signalstr[(sig)] : "unknown")
+#else /* HAVE_SIGNALENT_H */
+# define SIGNALSTR(sig) ("")
+#endif /* HAVE_SIGNALENT_H */
+
+
+/* signal handler */
+static void * sig_hdl(void * arg)
+{
+	sigset_t sig_main;
+	int sig = 0;
+	
+	TRACE_ENTRY();
+	fd_log_threadname("Main signal handler");
+	
+	sigemptyset(&sig_main);
+	sigaddset(&sig_main, SIGINT);
+	sigaddset(&sig_main, SIGTERM);
+	
+	CHECK_SYS_DO(  sigwait(&sig_main, &sig), TRACE_DEBUG(INFO, "Error in sigwait function") );
+	
+	TRACE_DEBUG(INFO, "Received signal %s (%d), exiting", SIGNALSTR(sig), sig);
+	CHECK_FCT_DO( fd_event_send(fd_g_config->g_fifo_main, FM_TERMINATE, NULL), exit(2) );
+	return NULL;
+}
+	
+/* The static configuration structure */
+static struct fd_config conf;
+struct fd_config * fd_g_config = &conf;
+
 /* Entry point */
 int main(int argc, char * argv[])
 {
+	int ret;
+	pthread_t sig_th;
+	sigset_t sig_all;
+	
+	memset(fd_g_config, 0, sizeof(struct fd_config));
+	sigfillset(&sig_all);
+	CHECK_POSIX(  pthread_sigmask(SIG_BLOCK, &sig_all, NULL)  );
+	
 	/* Initialize the library */
 	CHECK_FCT( fd_lib_init() );
 	
 	/* Name this thread */
 	fd_log_threadname("Main");
+	
+	/* Initialize the config */
+	CHECK_FCT( fd_conf_init() );
 
-	/* Initialize the dictionary */
-	CHECK_FCT( fd_dict_init(&fd_g_dict) );
+	/* Parse the command-line */
+	CHECK_FCT(  main_cmdline(argc, argv)  );
+	
+	/* Allow SIGINT and SIGTERM from this point */
+	CHECK_POSIX(  pthread_create(&sig_th, NULL, sig_hdl, NULL)  );
 	
 	/* Add definitions of the base protocol */
-	CHECK_FCT( fd_dict_base_protocol(fd_g_dict) );
+	CHECK_FCT( fd_dict_base_protocol(fd_g_config->g_dict) );
+	
+	/* Initialize other modules */
+	CHECK_FCT(  fd_ext_init()  );
+	
+	/* Parse the configuration file */
+	CHECK_FCT( fd_conf_parse() );
+	
+	/* Load the dynamic extensions */
+	CHECK_FCT(  fd_ext_load()  );
+	
+	/* Start the peer state machines */
+	
 	
-	TRACE_DEBUG(INFO, "freeDiameter daemon initialized.");
+	/* Now, just wait for events */
+	TRACE_DEBUG(INFO, FD_PROJECT_BINARY " daemon initialized.");
+	fd_conf_dump();
+	while (1) {
+		int code;
+		CHECK_FCT_DO(  fd_event_get(fd_g_config->g_fifo_main, &code, NULL),  break  );
+		switch (code) {
+			case FM_TERMINATE:
+				ret = 0;
+				goto end;
+			
+			default:
+				TRACE_DEBUG(INFO, "Unexpected event in the daemon (%d), terminating.\n", code);
+				ret = -1;
+				goto end;
+		}
+	}
 	
-	return 0;
+end:
+	TRACE_DEBUG(INFO, FD_PROJECT_BINARY " daemon is stopping...");
+	
+	/* cleanups */
+	CHECK_FCT( fd_thr_term(&sig_th) );
+	
+	return ret;
 }
"Welcome to our mercurial repository"