Mercurial > hg > waaad
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; }