X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=apps%2Fsilcd%2Fsilcd.c;h=cf3315a2cd126100a2611548ee6e1c271d797dda;hp=bfb50ca7082e2ee95e5fda05e75fee920a528be5;hb=d47a87b03b846e2333ef57b2c0d81f1644992964;hpb=5abf57fab042a9f9e4ea497cea5cdf6bb170ef62 diff --git a/apps/silcd/silcd.c b/apps/silcd/silcd.c index bfb50ca7..cf3315a2 100644 --- a/apps/silcd/silcd.c +++ b/apps/silcd/silcd.c @@ -1,23 +1,23 @@ /* silcd.c - + Author: Pekka Riikonen - Copyright (C) 1997 - 2001 Pekka Riikonen + Copyright (C) 1997 - 2002 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -/* +/* * Created: Wed Mar 19 00:17:12 1997 * * This is the main program for the SILC daemon. This parses command @@ -29,20 +29,24 @@ #include "server_internal.h" #include "version.h" +/* For now, we'll have this one server context global for this module. */ +static SilcServer silcd; + static void silc_usage(); static char *silc_server_create_identifier(); -static int +static int silc_server_create_key_pair(char *pkcs_name, int bits, char *path, - char *identifier, + char *identifier, SilcPublicKey *ret_pub_key, SilcPrivateKey *ret_prv_key); /* Long command line options */ -static struct option long_opts[] = +static struct option long_opts[] = { { "config-file", 1, NULL, 'f' }, { "debug", 1, NULL, 'd' }, { "help", 0, NULL, 'h' }, + { "foreground", 0, NULL, 'F' }, { "version", 0, NULL,'V' }, /* Key management options */ @@ -70,8 +74,9 @@ Usage: silcd [options]\n\ \n\ Generic Options:\n\ -f --config-file=FILE Alternate configuration file\n\ - -d --debug=string Enable debugging (no daemon)\n\ + -d --debug=string Enable debugging (Implies --foreground)\n\ -h --help Display this message\n\ + -F --foreground Dont fork\n\ -V --version Display version\n\ \n\ Key Management Options:\n\ @@ -95,22 +100,59 @@ Usage: silcd [options]\n\ exit(0); } +/* Dies if a *valid* pid file exists already */ + +static void silc_server_checkpid(SilcServer silcd) +{ + if (silcd->config->server_info->pid_file) { + int oldpid; + char *buf; + uint32 buf_len; + + SILC_LOG_DEBUG(("Checking for another silcd running")); + buf = silc_file_readfile(silcd->config->server_info->pid_file, &buf_len); + if (!buf) + return; + oldpid = atoi(buf); + silc_free(buf); + if (oldpid <= 0) + return; + kill(oldpid, SIGCHLD); /* this signal does nothing, check if alive */ + if (errno != ESRCH) { + fprintf(stderr, "\nI detected another daemon running with the same pid file.\n"); + fprintf(stderr, "Please change the config file, or erase the %s\n", + silcd->config->server_info->pid_file); + exit(1); + } + } +} + +static void got_hup(int z) +{ + /* First, reset all log files (they might have been deleted) */ + silc_log_reset_all(); + silc_log_flush_all(); +} + +static void stop_server(int z) +{ + /* Stop scheduler, the program will stop eventually after noticing + that the scheduler is down. */ + silc_schedule_stop(silcd->schedule); +} + int main(int argc, char **argv) { - int ret; - int opt, option_index; + int ret, opt, option_index; char *config_file = NULL; - SilcServer silcd; + bool foreground = FALSE; struct sigaction sa; - char pid[10]; - - silc_debug = FALSE; /* Parse command line arguments */ if (argc > 1) { - while ((opt = getopt_long(argc, argv, "cf:d:hVC:", + while ((opt = getopt_long(argc, argv, "cf:d:hFVC:", long_opts, &option_index)) != EOF) { - switch(opt) + switch(opt) { case 'h': silc_usage(); @@ -124,11 +166,14 @@ int main(int argc, char **argv) exit(0); break; case 'd': +#ifdef SILC_DEBUG silc_debug = TRUE; silc_debug_hexdump = TRUE; silc_log_set_debug_string(optarg); -#ifndef SILC_DEBUG - fprintf(stdout, + foreground = TRUE; + silc_log_quick = TRUE; +#else + fprintf(stdout, "Run-time debugging is not enabled. To enable it recompile\n" "the server with --enable-debug configuration option.\n"); #endif @@ -136,6 +181,9 @@ int main(int argc, char **argv) case 'f': config_file = strdup(optarg); break; + case 'F': + foreground = TRUE; + break; /* * Key management options @@ -190,6 +238,9 @@ int main(int argc, char **argv) if (silcd->config == NULL) goto fail; + /* Check for another silcd running */ + silc_server_checkpid(silcd); + /* Initialize the server */ ret = silc_server_init(silcd); if (ret == FALSE) @@ -200,27 +251,39 @@ int main(int argc, char **argv) sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaction(SIGPIPE, &sa, NULL); - - if (silc_debug == FALSE) - /* Before running the server, fork to background and set - both user and group no non-root */ + sa.sa_handler = got_hup; + sigaction(SIGHUP, &sa, NULL); + sa.sa_handler = stop_server; + sigaction(SIGTERM, &sa, NULL); + sa.sa_handler = stop_server; + sigaction(SIGINT, &sa, NULL); + + /* Before running the server, fork to background. */ + if (!foreground) silc_server_daemonise(silcd); - /* Set /var/run/silcd.pid */ - unlink(SILC_SERVER_PID_FILE); - memset(pid, 0, sizeof(pid)); - snprintf(pid, sizeof(pid) - 1, "%d\n", getpid()); - silc_file_writefile(SILC_SERVER_PID_FILE, pid, strlen(pid)); - + /* If set, write pid to file */ + if (silcd->config->server_info->pid_file) { + char buf[10], *pidfile = silcd->config->server_info->pid_file; + unlink(pidfile); + snprintf(buf, sizeof(buf) - 1, "%d\n", getpid()); + silc_file_writefile(pidfile, buf, strlen(buf)); + } + + /* Drop root. */ + silc_server_drop(silcd); + /* Run the server. When this returns the server has been stopped and we will exit. */ silc_server_run(silcd); - /* Stop the server. This probably has been done already but it - doesn't hurt to do it here again. */ + /* Stop the server and free it. */ silc_server_stop(silcd); silc_server_free(silcd); - + + /* Flush the logging system */ + silc_log_flush_all(); + exit(0); fail: exit(1);