mirror of
https://github.com/optim-enterprises-bv/nDPId.git
synced 2025-10-30 01:42:22 +00:00
206 lines
3.9 KiB
C
206 lines
3.9 KiB
C
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <grp.h>
|
|
#include <pwd.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <syslog.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
#include "utils.h"
|
|
|
|
typedef char pid_str[16];
|
|
|
|
static int daemonize = 0;
|
|
|
|
void daemonize_enable(void)
|
|
{
|
|
daemonize = 1;
|
|
}
|
|
|
|
static int is_daemon_running(char const * const pidfile, pid_str ps)
|
|
{
|
|
int pfd = open(pidfile, O_RDONLY, 0);
|
|
char proc_path[32];
|
|
|
|
if (pfd < 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (read(pfd, ps, sizeof(pid_str)) <= 0)
|
|
{
|
|
close(pfd);
|
|
return 1;
|
|
}
|
|
|
|
close(pfd);
|
|
|
|
if (snprintf(proc_path, sizeof(pid_str), "/proc/%s", ps) <= 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if (access(proc_path, F_OK) == 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int create_pidfile(char const * const pidfile)
|
|
{
|
|
int pfd;
|
|
|
|
if (is_path_absolute("Pidfile", pidfile) != 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
pfd = open(pidfile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
|
|
|
if (pfd < 0)
|
|
{
|
|
syslog(LOG_DAEMON | LOG_ERR, "Could open pidfile %s for writing: %s", pidfile, strerror(errno));
|
|
return 1;
|
|
}
|
|
|
|
if (dprintf(pfd, "%d", getpid()) <= 0)
|
|
{
|
|
close(pfd);
|
|
return 1;
|
|
}
|
|
|
|
close(pfd);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int is_path_absolute(char const * const prefix, char const * const path)
|
|
{
|
|
if (path[0] != '/')
|
|
{
|
|
syslog(LOG_DAEMON | LOG_ERR,
|
|
"%s path must be absolut i.e. starting with a `/', path given: `%s'",
|
|
prefix,
|
|
path);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int daemonize_with_pidfile(char const * const pidfile)
|
|
{
|
|
pid_str ps = {};
|
|
|
|
if (daemonize != 0)
|
|
{
|
|
if (is_daemon_running(pidfile, ps) != 0)
|
|
{
|
|
syslog(LOG_DAEMON | LOG_ERR, "Pidfile %s found and daemon %s still running", pidfile, ps);
|
|
return 1;
|
|
}
|
|
|
|
if (daemon(0, 0) != 0)
|
|
{
|
|
syslog(LOG_DAEMON | LOG_ERR, "daemon: %s", strerror(errno));
|
|
return 1;
|
|
}
|
|
|
|
if (create_pidfile(pidfile) != 0)
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int daemonize_shutdown(char const * const pidfile)
|
|
{
|
|
if (daemonize != 0)
|
|
{
|
|
if (unlink(pidfile) != 0)
|
|
{
|
|
syslog(LOG_DAEMON | LOG_ERR, "Could not unlink pidfile %s: %s", pidfile, strerror(errno));
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int change_user_group(char const * const user,
|
|
char const * const group,
|
|
char const * const pidfile,
|
|
char const * const uds_collector_path,
|
|
char const * const uds_distributor_path)
|
|
{
|
|
struct passwd * pwd;
|
|
struct group * grp;
|
|
gid_t gid;
|
|
|
|
if (getuid() != 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (user == NULL)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
pwd = getpwnam(user);
|
|
if (pwd == NULL)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if (group != NULL)
|
|
{
|
|
grp = getgrnam(group);
|
|
if (grp == NULL)
|
|
{
|
|
return 1;
|
|
}
|
|
gid = grp->gr_gid;
|
|
}
|
|
else
|
|
{
|
|
gid = pwd->pw_gid;
|
|
}
|
|
|
|
if (uds_collector_path != NULL)
|
|
{
|
|
chmod(uds_collector_path, S_IRUSR | S_IWUSR);
|
|
chown(uds_collector_path, pwd->pw_uid, gid);
|
|
}
|
|
if (uds_distributor_path != NULL)
|
|
{
|
|
chmod(uds_distributor_path, S_IRUSR | S_IWUSR | S_IRGRP);
|
|
chown(uds_distributor_path, pwd->pw_uid, gid);
|
|
}
|
|
if (pidfile != NULL)
|
|
{
|
|
chown(pidfile, pwd->pw_uid, gid);
|
|
}
|
|
return setregid(gid, gid) != 0 || setreuid(pwd->pw_uid, pwd->pw_uid);
|
|
}
|
|
|
|
char const * get_nDPId_version()
|
|
{
|
|
return "nDPId version "
|
|
#ifdef GIT_VERSION
|
|
GIT_VERSION
|
|
#else
|
|
"unknown"
|
|
#endif
|
|
"\n"
|
|
"(C) 2020-2021 Toni Uhlig\n"
|
|
"Please report BUGs to toni@impl.cc\n";
|
|
}
|