From a3f65c7050f2099b034c43c5f6476e8a5229d69c Mon Sep 17 00:00:00 2001 From: kakwa Date: Thu, 1 Sep 2016 19:43:29 +0200 Subject: [PATCH] fix the way relative paths are handled and pid file handler * add a pid file option on command line + implement it * make the relative path in conf param relative to the configuration file directory and not the running directory --- inc/utils.h | 2 ++ src/cmd/uts-server.c | 41 +++++++++++++++++++++++++++++++++++------ src/lib/utils.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/inc/utils.h b/inc/utils.h index f978e01..461819a 100644 --- a/inc/utils.h +++ b/inc/utils.h @@ -1,6 +1,8 @@ #include "rfc3161.h" void skeleton_daemon(); +int init_pid(char *pidfile_path); +int write_pid(char *pidfile_path); void uts_logger(rfc3161_context *ct, int priority, char *fmt, ...); void log_hex(rfc3161_context *ct, int priority, char *id, unsigned char *content, int content_length); diff --git a/src/cmd/uts-server.c b/src/cmd/uts-server.c index d6927ff..eba8e57 100644 --- a/src/cmd/uts-server.c +++ b/src/cmd/uts-server.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "http.h" const char *argp_program_version = UTS_VERSION; @@ -18,6 +19,7 @@ static char doc[] = "\nUTS micro timestamp server (RFC 3161)"; static struct argp_option options[] = { {"conffile", 'c', "CONFFILE", 0, "Path to configuration file"}, {"daemonize", 'd', 0, 0, "Launch as a daemon"}, + {"pidfile", 'p', "PIDFILE", 0, "Path to pid file"}, {"debug", 'D', 0, 0, "STDOUT debugging"}, {0}}; @@ -29,6 +31,7 @@ struct arguments { int daemonize; bool stdout_dbg; char *conffile; + char *pidfile; }; static error_t parse_opt(int key, char *arg, struct argp_state *state) { @@ -46,6 +49,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) { case 'c': arguments->conffile = arg; break; + case 'p': + arguments->pidfile = arg; + break; default: return ARGP_ERR_UNKNOWN; } @@ -58,27 +64,50 @@ static struct argp argp = {options, parse_opt, args_doc, doc}; int main(int argc, char **argv) { struct arguments args; args.conffile = NULL; + args.pidfile = NULL; args.daemonize = 0; args.stdout_dbg = 0; argp_parse(&argp, argc, argv, 0, 0, &args); int ret = EXIT_SUCCESS; - // get the current path, the configuration can be relative to this path - char conf_wd[PATH_MAX]; - if (getcwd(conf_wd, sizeof(conf_wd)) == NULL) { - syslog(LOG_CRIT, "unable to get the current, uts-server start failed"); + // get the full path of the configuration (daemon -> chdir to / concequently + // full path is necessary) + char conf_fp[PATH_MAX]; + if (realpath(args.conffile, conf_fp) == NULL) { + syslog(LOG_CRIT, "unable to get the full path of the configuration " + "file, uts-server start failed"); return EXIT_FAILURE; } + init_pid(args.pidfile); + // get the full path for the pid file + char pid_file[PATH_MAX]; + if (realpath(args.pidfile, pid_file) == NULL) { + syslog(LOG_CRIT, "unable to get the full path of the pid " + "file, uts-server start failed"); + return EXIT_FAILURE; + } + + // get the directory containing the configuration file + // other uts-server files (ca, certs, etc) can be declared relatively to the + // configuration file + char *conf_wd = strdup(conf_fp); + dirname(conf_wd); + if (args.daemonize) skeleton_daemon(); syslog(LOG_NOTICE, "uts-server daemon starting with conf '%s' from working dir '%s'", - args.conffile, conf_wd); + conf_fp, conf_wd); + + if (write_pid(pid_file) == 0) { + syslog(LOG_CRIT, "failed to write pid file '%s'", pid_file); + return EXIT_FAILURE; + } while (1) { - ret = http_server_start(args.conffile, conf_wd, args.stdout_dbg); + ret = http_server_start(conf_fp, conf_wd, args.stdout_dbg); break; } diff --git a/src/lib/utils.c b/src/lib/utils.c index d34ff02..ec5514a 100644 --- a/src/lib/utils.c +++ b/src/lib/utils.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include "utils.h" typedef struct _code { @@ -38,6 +40,47 @@ static void signal_handler_up(int sig_num) { g_uts_sig_up = sig_num; } +int init_pid(char *pidfile_path) { + // if pidfile_path is null, the user did not request one + // exit success + if (pidfile_path == NULL) + return 1; + + int fd = open(pidfile_path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + // in case we can't open it + if (fd == -1) { + syslog(LOG_CRIT, "failed to open the pid file"); + return 0; + } + + close(fd); + return 1; +} + +int write_pid(char *pidfile_path) { + // if pidfile_path is null, the user did not request one + // exit success + if (pidfile_path == NULL) + return 1; + + int fd = open(pidfile_path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + // in case we can't open it + if (fd == -1) { + syslog(LOG_CRIT, "failed to open the pid file"); + return 0; + } + + char buf[100]; + snprintf(buf, 100, "%ld\n", (long)getpid()); + if (write(fd, buf, strlen(buf)) != strlen(buf)) { + syslog(LOG_CRIT, "failed to write the pid"); + close(fd); + return 0; + } + close(fd); + return 1; +} + void skeleton_daemon() { pid_t pid;