comparison freeDiameterd/main.c @ 658:f198d16fa7f4

Initial commit for 1.1.0: * Restructuring: * libfreeDiameter: - renamed folder & binary into libfdproto - renamed libfD.h into fdproto-internal.h - removed signals management (replaced by triggers in libfdcore) * freeDiameter split into: - libfdcore (most contents) - renamed fD.h into fdcore-internal.h - added core.c for framework init/shutdown. - new triggers mechanism in events.c. - freeDiameterd (main, command line parsing, signals management) * tests: - now in top-level directory tests. * other changes: - fd_dict_new now returns 0 on duplicate identical entries. - fixes in dict_legacy_xml - fixes in some dictionaries - moved FD_DEFAULT_CONF_FILENAME definition to freeDiameter-host.h
author Sebastien Decugis <sdecugis@nict.go.jp>
date Fri, 14 Jan 2011 15:15:23 +0900
parents freeDiameter/main.c@e1c6f45f5fcd
children 2e94ef0515d7
comparison
equal deleted inserted replaced
656:5b05d85682f1 658:f198d16fa7f4
1 /*********************************************************************************************************
2 * Software License Agreement (BSD License) *
3 * Author: Sebastien Decugis <sdecugis@nict.go.jp> *
4 * *
5 * Copyright (c) 2010, WIDE Project and NICT *
6 * All rights reserved. *
7 * *
8 * Redistribution and use of this software in source and binary forms, with or without modification, are *
9 * permitted provided that the following conditions are met: *
10 * *
11 * * Redistributions of source code must retain the above *
12 * copyright notice, this list of conditions and the *
13 * following disclaimer. *
14 * *
15 * * Redistributions in binary form must reproduce the above *
16 * copyright notice, this list of conditions and the *
17 * following disclaimer in the documentation and/or other *
18 * materials provided with the distribution. *
19 * *
20 * * Neither the name of the WIDE Project or NICT nor the *
21 * names of its contributors may be used to endorse or *
22 * promote products derived from this software without *
23 * specific prior written permission of WIDE Project and *
24 * NICT. *
25 * *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
27 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
28 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
29 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
32 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
34 *********************************************************************************************************/
35
36 #include <freeDiameter/freeDiameter-host.h>
37 #include <freeDiameter/libfdcore.h>
38
39 #include <signal.h>
40 #include <getopt.h>
41 #include <locale.h>
42
43
44 /* forward declarations */
45 static int main_cmdline(int argc, char *argv[]);
46 static void * catch_signals(void * arg);
47 static pthread_t signals_thr;
48
49 static char *conffile = NULL;
50 static int gnutls_debug = 0;
51
52 /* gnutls debug */
53 static void fd_gnutls_debug(int level, const char * str) {
54 fd_log_debug(" [gnutls:%d] %s", level, str);
55 }
56
57
58 /* freeDiameter starting point */
59 int main(int argc, char * argv[])
60 {
61 int ret;
62 sigset_t sig_all;
63
64 /* Block all signals from the current thread and all its future children */
65 sigfillset(&sig_all);
66 ret = pthread_sigmask(SIG_BLOCK, &sig_all, NULL);
67 ASSERT(ret == 0);
68
69 /* Parse the command-line */
70 ret = main_cmdline(argc, argv);
71 if (ret != 0) {
72 return ret;
73 }
74
75 /* Initialize the core library */
76 ret = fd_core_initialize();
77 if (ret != 0) {
78 fprintf(stderr, "An error occurred during freeDiameter core library initialization.\n");
79 return ret;
80 }
81
82 /* Set gnutls debug level ? */
83 if (gnutls_debug) {
84 gnutls_global_set_log_function((gnutls_log_func)fd_gnutls_debug);
85 gnutls_global_set_log_level (gnutls_debug);
86 TRACE_DEBUG(INFO, "Enabled GNUTLS debug at level %d", gnutls_debug);
87 }
88
89 /* Allow SIGINT and SIGTERM from this point to terminate the application */
90 CHECK_POSIX( pthread_create(&signals_thr, NULL, catch_signals, NULL) );
91
92 /* Parse the configuration file */
93 CHECK_FCT( fd_core_parseconf(conffile) );
94
95 /* Start the servers */
96 CHECK_FCT( fd_core_start() );
97
98 TRACE_DEBUG(INFO, FD_PROJECT_BINARY " daemon initialized.");
99
100 /* Now, just wait for termination */
101 CHECK_FCT( fd_core_wait_shutdown_complete() );
102
103 /* Just in case it was not the result of a signal, we cancel signals_thr */
104 fd_thr_term(&signals_thr);
105
106 return 0;
107 }
108
109
110 /* Display package version */
111 static void main_version_core(void)
112 {
113 printf("%s, version %d.%d.%d"
114 #ifdef HG_VERSION
115 " (r%s"
116 # ifdef PACKAGE_HG_REVISION
117 "/%s"
118 # endif /* PACKAGE_HG_VERSION */
119 ")"
120 #endif /* HG_VERSION */
121 " (libfdcore: %s)\n",
122 FD_PROJECT_NAME, FD_PROJECT_VERSION_MAJOR, FD_PROJECT_VERSION_MINOR, FD_PROJECT_VERSION_REV
123 #ifdef HG_VERSION
124 , HG_VERSION
125 # ifdef PACKAGE_HG_REVISION
126 , PACKAGE_HG_REVISION
127 # endif /* PACKAGE_HG_VERSION */
128 #endif /* HG_VERSION */
129 , fd_core_version());
130 }
131
132 /* Display package version and general info */
133 static void main_version(void)
134 {
135 main_version_core();
136 printf( "%s\n", FD_PROJECT_COPYRIGHT);
137 printf( "\nSee " FD_PROJECT_NAME " homepage at http://www.freediameter.net/\n"
138 " for information, updates and bug reports on this software.\n");
139 }
140
141 /* Print command-line options */
142 static void main_help( void )
143 {
144 main_version_core();
145 printf( " This daemon is an implementation of the Diameter protocol\n"
146 " used for Authentication, Authorization, and Accounting (AAA).\n");
147 printf("\nUsage: " FD_PROJECT_BINARY " [OPTIONS]...\n");
148 printf( " -h, --help Print help and exit\n"
149 " -V, --version Print version and exit\n"
150 " -c, --config=filename Read configuration from this file instead of the \n"
151 " default location (" DEFAULT_CONF_PATH "/" FD_DEFAULT_CONF_FILENAME ").\n");
152 printf( "\nDebug:\n"
153 " These options are mostly useful for developers\n"
154 " -l, --dbglocale Set the locale for error messages\n"
155 " -d, --debug Increase verbosity of debug messages\n"
156 " -q, --quiet Decrease verbosity then remove debug messages\n"
157 " --dbg_gnutls <int> Enable GNU TLS debug at level <int>\n");
158 }
159
160 /* Parse the command-line */
161 static int main_cmdline(int argc, char *argv[])
162 {
163 int c;
164 int option_index = 0;
165 char * locale;
166
167 struct option long_options[] = {
168 { "help", no_argument, NULL, 'h' },
169 { "version", no_argument, NULL, 'V' },
170 { "config", required_argument, NULL, 'c' },
171 { "debug", no_argument, NULL, 'd' },
172 { "quiet", no_argument, NULL, 'q' },
173 { "dbglocale", optional_argument, NULL, 'l' },
174 { "dbg_func", required_argument, NULL, 'f' },
175 { "dbg_file", required_argument, NULL, 'F' },
176 { "dbg_gnutls", required_argument, NULL, 'g' },
177 { NULL, 0, NULL, 0 }
178 };
179
180 /* Loop on arguments */
181 while (1) {
182 c = getopt_long (argc, argv, "hVc:dql:", long_options, &option_index);
183 if (c == -1)
184 break; /* Exit from the loop. */
185
186 switch (c) {
187 case 'h': /* Print help and exit. */
188 main_help();
189 exit(0);
190
191 case 'V': /* Print version and exit. */
192 main_version();
193 exit(0);
194
195 case 'c': /* Read configuration from this file instead of the default location.. */
196 if (optarg == NULL ) {
197 fprintf(stderr, "Missing argument with --config directive\n");
198 return EINVAL;
199 }
200 conffile = optarg;
201 break;
202
203 case 'l': /* Change the locale. */
204 locale = setlocale(LC_ALL, optarg?:"");
205 if (!locale) {
206 fprintf(stderr, "Unable to set locale (%s)\n", optarg);
207 return EINVAL;
208 }
209 break;
210
211 case 'd': /* Increase verbosity of debug messages. */
212 fd_g_debug_lvl++;
213 break;
214
215 case 'f': /* Full debug for the function with this name. */
216 #ifdef DEBUG
217 fd_debug_one_function = optarg;
218 #else /* DEBUG */
219 fprintf(stderr, "Error: must compile with DEBUG support to use --dbg_func feature!\n");
220 return EINVAL;
221 #endif /* DEBUG */
222 break;
223
224 case 'F': /* Full debug for the file with this name. */
225 #ifdef DEBUG
226 fd_debug_one_file = basename(optarg);
227 #else /* DEBUG */
228 fprintf(stderr, "Error: must compile with DEBUG support to use --dbg_file feature!\n");
229 return EINVAL;
230 #endif /* DEBUG */
231 break;
232
233 case 'g': /* Set a debug level and function for GNU TLS calls. */
234 gnutls_debug = (int)atoi(optarg);
235 break;
236
237 case 'q': /* Decrease verbosity then remove debug messages. */
238 fd_g_debug_lvl--;
239 break;
240
241 case '?': /* Invalid option. */
242 /* `getopt_long' already printed an error message. */
243 fprintf(stderr, "getopt_long found an invalid character\n");
244 return EINVAL;
245
246 default: /* bug: option not considered. */
247 fprintf(stderr, "A command-line option is missing in parser: %c\n", c);
248 ASSERT(0);
249 return EINVAL;
250 }
251 }
252
253 return 0;
254 }
255
256 /* Handle some signals */
257 static void * catch_signals(void * arg)
258 {
259 sigset_t ss;
260 fd_log_threadname ( "signals catcher" );
261
262 sigemptyset(&ss);
263
264 /* Signals that terminate the daemon */
265 sigaddset(&ss, SIGTERM);
266 sigaddset(&ss, SIGINT);
267
268 /* Signals that send an event */
269 sigaddset(&ss, SIGUSR1);
270 sigaddset(&ss, SIGUSR2);
271
272 /* Now loop on the reception of the signal */
273 while (1) {
274 int sig, *ps;
275
276 /* Wait to receive the next signal */
277 CHECK_POSIX_DO( sigwait(&ss, &sig), break );
278
279 TRACE_DEBUG(FULL, "Signal %d caught", sig);
280
281 switch (sig) {
282 case SIGUSR1:
283 case SIGUSR2:
284 CHECK_MALLOC_DO( ps = malloc(sizeof(int)), goto out);
285 *ps = sig;
286 CHECK_FCT_DO( fd_event_send(fd_g_config->cnf_main_ev, FDEV_TRIGGER, sizeof(int), ps), goto out );
287 break;
288
289 case SIGINT:
290 case SIGTERM:
291 CHECK_FCT_DO( fd_core_shutdown(), goto out );
292
293 }
294 }
295 out:
296 /* Better way to handle this ? */
297 ASSERT(0);
298 return NULL;
299 }
"Welcome to our mercurial repository"