view waaad/main.c @ 371:e86dba02630a

Updated copyright information
author Sebastien Decugis <sdecugis@nict.go.jp>
date Mon, 25 May 2009 14:51:46 +0900
parents 6ca21598562a
children
line wrap: on
line source

/*********************************************************************************************************
* Software License Agreement (BSD License)                                                               *
* Author: Sebastien Decugis <sdecugis@nict.go.jp>							 *
*													 *
* Copyright (c) 2009, WIDE Project and NICT								 *
* All rights reserved.											 *
* 													 *
* Redistribution and use of this software in source and binary forms, with or without modification, are  *
* permitted provided that the following conditions are met:						 *
* 													 *
* * Redistributions of source code must retain the above 						 *
*   copyright notice, this list of conditions and the 							 *
*   following disclaimer.										 *
*    													 *
* * Redistributions in binary form must reproduce the above 						 *
*   copyright notice, this list of conditions and the 							 *
*   following disclaimer in the documentation and/or other						 *
*   materials provided with the distribution.								 *
* 													 *
* * Neither the name of the WIDE Project or NICT nor the 						 *
*   names of its contributors may be used to endorse or 						 *
*   promote products derived from this software without 						 *
*   specific prior written permission of WIDE Project and 						 *
*   NICT.												 *
* 													 *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 	 *
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 	 *
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
*********************************************************************************************************/

/* waaad main file.
 *
 * This file contains the main() function of the daemon.
 *
 * It is responsible for initializing and starting all other modules.
 *
 */

#include "waaad-internal.h"

#include <signal.h>
#include <getopt.h>

/* Display package version */
static void main_version_core(void)
{
	printf("%s (%s) version %s"
#ifdef HG_VERSION
		" (r%s"
#ifdef PACKAGE_HG_REVISION
		"/%s"
#endif /* PACKAGE_HG_VERSION */
		")"
#endif /* HG_VERSION */
		"\n", 
		CMAKE_PROJECT_NAME, PROJECT_NAME, PROJECT_VERSION
#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( "\n%s\n", PROJECT_COPYRIGHT);
	printf( "\nSee " CMAKE_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("\nThis daemon is an implementation of the Diameter protocol.\n");
	printf("\nUsage: " PROJECT_NAME " [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.\n");
 	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:
 * return 0: OK
 * return 1: ERROR
 * return 2: No error, but program must exit
 */
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();
				return 2;

			case 'V':	/* Print version and exit.  */
				main_version();
				return 2;

			case 'c':	/* Read configuration from this file instead of the default location..  */
				if (optarg) {
					g_conf->filepath = optarg;
				} else {
					log_error("You must provide a filename when -c flag is used.\n");
					return 1;
				}
				break;

			case 'd':	/* Increase verbosity of debug messages.  */
				waaad_verbosity++;
				break;
				
			case 'q':	/* Decrease verbosity then remove debug messages.  */
				waaad_verbosity--;
				break;

			case '?':	/* Invalid option.  */
				/* `getopt_long' already printed an error message.  */
				TRACE_DEBUG(INFO, "getopt_long found an invalid character\n");
				return 1;

			default:	/* bug: option not considered.  */
				TRACE_DEBUG(INFO, "A command-line option is missing in parser: %c\n", c);
				ASSERT(0);
				return 1;
		}
	}
		
	return 0;
	
}

/* signal handler */
static void * sig_hdl(void * arg)
{
	sigset_t sig_main;
	int sig;
	int ret;
	
	TRACE_ENTRY();
	
	sigemptyset(&sig_main);
	sigaddset(&sig_main, SIGINT);
	sigaddset(&sig_main, SIGTERM);
	
	while (1) {
		CHECK_SYS_DO(  sigwait(&sig_main, &sig),
			{
				CHECK_FCT_DO(  uti_event_send(WDE_ERROR),  /* nothing more */  );
				break;
			}  );
		
		switch (sig) {
			case SIGTERM:
				CHECK_FCT_DO(  ret = uti_event_send(WDE_SIGTERM),  goto out  );
				break;
			case SIGINT:
				CHECK_FCT_DO(  ret = uti_event_send(WDE_SIGINT),  goto out  );
				break;
			default:
				ASSERT(0);
		}
	}
out:	
	TRACE_DEBUG(FULL, "Signal handler thread terminating...");
	return NULL;
}
	

/* Main daemon function */
int main(int argc, char * argv[])
{
	int ret;
	pthread_t sig_th;
	sigset_t sig_all;
	
	/* First of all, initialize the conf and log modules. */
	ret = conf_init();
	if (ret != 0) {
		fprintf(stderr, "Unable to initialize the conf facility\n");
		return -1;
	}
	
	ret = log_init(g_conf->log_to);
	if (ret != 0) {
		fprintf(stderr, "Unable to initialize the log facility\n");
		return -1;
	}
	
	THREAD_NAME( "Main" );
	
	/* Then the signal handler: block all signals for all future threads. Extensions may unblock signals that are not used in sig_hdl */
	sigfillset(&sig_all);
	CHECK_POSIX_DO(  pthread_sigmask(SIG_BLOCK, &sig_all, NULL),  return -1  );
	CHECK_POSIX_DO(  pthread_create(&sig_th, NULL, sig_hdl, NULL),  return -1  );
	
	/* Then, initialize other modules */
	CHECK_FCT_DO(  ext_init(), goto error  );
	CHECK_FCT_DO(  dict_init(), goto error  );
	CHECK_FCT_DO(  msg_init(), goto error  );
	CHECK_FCT_DO(  meq_init(), goto error  );
	CHECK_FCT_DO(  peer_init(), goto error  );
	CHECK_FCT_DO(  sess_init(), goto error  );
	CHECK_FCT_DO(  rt_init(), goto error  );
	CHECK_FCT_DO(  disp_init(), goto error  );
	CHECK_FCT_DO(  sec_init(), goto error  );
	
	/* Parse the command-line options */
	ret = main_cmdline(argc, argv);
	if (ret != 0) {
		if (ret == 2)
			ret = 0;
		goto end;
	}
	
	/* Now, parse the configuration file */
	CHECK_FCT_DO(  conf_parse(), 
		{
			log_error("Failed to parse the configuration file.\n");
			goto error;
		}  );
	
	/* Load the extensions */
	CHECK_FCT_DO(  ext_load(), goto error  );
	
	#if 0
	/* DEBUG: dump the dictionary content */
	dump_dictionary();
	#endif /* 0 */

	/* Allow the peer module to start */
	CHECK_FCT_DO(  peer_start(),
		{
			log_error("Failed to open server sockets or start connections to other peers\n");
			goto error;
		}  );
	
	/* Now wait for events */
	while (1) {
		uti_event_t ev;
		
		CHECK_FCT_DO(  uti_event_receive(&ev),  goto end  );
		
		switch (ev) {
			case WDE_SIGTERM:
			case WDE_SIGINT:
				TRACE_DEBUG(INFO, "Received signal to terminate");
				ret = 0;
				goto end;
			
			case WDE_ERROR:
			default:
				log_error("An unrecoverable error occurred, terminating... Turn on debug for more information.\n");
				ret = -1;
				goto end;
		}
	}
error:
	log_error("An internal error occurred during initialization, turn on debug for detail\n");
	ret = -1;
	
	/* Terminate */
end:
	TRACE_DEBUG(FULL, "Entering 'end' section of main function.");
	
	CHECK_FCT_DO(  peer_fini(),  /* continue */  );
	CHECK_FCT_DO(  ext_fini(),  /* continue */  );
	CHECK_FCT_DO(  sec_fini(),  /* continue */  );
	CHECK_FCT_DO(  disp_fini(),  /* continue */  );
	CHECK_FCT_DO(  rt_fini(),  /* continue */  );
	CHECK_FCT_DO(  sess_fini(),  /* continue */  );
	CHECK_FCT_DO(  msg_fini(),  /* continue */  );
	CHECK_FCT_DO(  meq_fini(),  /* continue */  );
	CHECK_FCT_DO(  dict_fini(),  /* continue */  );
	
	CHECK_POSIX_DO(  pthread_cancel(sig_th),  /* continue */  );
	CHECK_POSIX_DO(  pthread_join(sig_th, NULL),  /* continue */  );
	
	(void)log_fini();
	(void)conf_fini();
	
	return ret;
}
"Welcome to our mercurial repository"