From 0c564ddd977451d93d5cf6898a66ebd608e32862 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 12 Sep 2022 13:27:58 +0200 Subject: Merging upstream version 2.1.0. Signed-off-by: Daniel Baumann --- src/daemon.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/dnscap.1.in | 3 +++ src/options.c | 11 +++++++++++ src/options.h | 4 ++++ 4 files changed, 70 insertions(+) (limited to 'src') diff --git a/src/daemon.c b/src/daemon.c index 88ce785..596b863 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -224,6 +224,57 @@ void drop_privileges(void) #endif } +void write_pid_file(void) +{ + FILE* fp; + int fd, flags; + struct flock lock; + + if (!options.pid_file) + return; + + if ((fd = open(options.pid_file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) == -1) { + fprintf(stderr, "unable to open PID file %s: %s", options.pid_file, strerror(errno)); + exit(1); + } + + if ((flags = fcntl(fd, F_GETFD)) == -1) { + fprintf(stderr, "unable to get PID file flags: %s", strerror(errno)); + exit(1); + } + flags |= FD_CLOEXEC; + if (fcntl(fd, F_SETFD, flags) == 1) { + fprintf(stderr, "unable to set PID file flags: %s", strerror(errno)); + exit(1); + } + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + + if (fcntl(fd, F_SETLK, &lock) == -1) { + if (errno == EACCES || errno == EAGAIN) { + fprintf(stderr, "PID file locked by other process"); + exit(1); + } + + fprintf(stderr, "unable to lock PID file: %s", strerror(errno)); + exit(1); + } + + if (ftruncate(fd, 0) == -1) { + fprintf(stderr, "unable to truncate PID file: %s", strerror(errno)); + exit(1); + } + + fp = fdopen(fd, "w"); + if (!fp || fprintf(fp, "%d\n", getpid()) < 1 || fflush(fp)) { + fprintf(stderr, "unable to write to PID file: %s", strerror(errno)); + exit(1); + } +} + void daemonize(void) { pid_t pid; @@ -235,6 +286,7 @@ void daemonize(void) exit(1); } else if (pid > 0) exit(0); + write_pid_file(); openlog("dnscap", 0, LOG_DAEMON); if (setsid() < 0) { logerr("setsid failed: %s", strerror(errno)); diff --git a/src/dnscap.1.in b/src/dnscap.1.in index f33fcfc..58c4b90 100644 --- a/src/dnscap.1.in +++ b/src/dnscap.1.in @@ -163,6 +163,9 @@ functions, unless options .B \-N is given or only reading from files. .TP +.BI "\-o pid_file" =... +Specify the file to write the PID to when running as a daemon (default none). +.TP .BI "\-o user" =... Specify the user to drop privileges to (default nobody). .TP diff --git a/src/options.c b/src/options.c index 29a5dad..8d03c26 100644 --- a/src/options.c +++ b/src/options.c @@ -228,6 +228,13 @@ int option_parse(options_t* options, const char* option) options->bpf_hosts_apply_all = 1; return 0; } + } else if (have("pid_file")) { + if (options->pid_file) { + free(options->pid_file); + } + if ((options->pid_file = strdup(argument))) { + return 0; + } } return 1; @@ -244,5 +251,9 @@ void options_free(options_t* options) free(options->group); options->group = 0; } + if (options->pid_file) { + free(options->pid_file); + options->pid_file = 0; + } } } diff --git a/src/options.h b/src/options.h index 40e0ee8..99acb8d 100644 --- a/src/options.h +++ b/src/options.h @@ -71,6 +71,8 @@ enum dump_format { 0, 0, 0, 0, 0, 0, 0, \ \ 0, 0, 0, 0, 0, \ +\ + 0, \ \ 0 \ } @@ -113,6 +115,8 @@ struct options { int reassemble_tcp_bfbparsedns; int bpf_hosts_apply_all; + + char* pid_file; }; int option_parse(options_t* options, const char* option); -- cgit v1.2.3