mirror of
https://github.com/badaix/snapcast.git
synced 2025-07-07 03:37:42 +02:00
check permissions for server.json
This commit is contained in:
parent
f6209d7dce
commit
2955b20e9d
7 changed files with 230 additions and 163 deletions
|
@ -50,13 +50,13 @@ else ifeq ($(TARGET), OPENWRT)
|
||||||
STRIP = echo
|
STRIP = echo
|
||||||
CXXFLAGS += -pthread -DNO_CPP11_STRING -DHAS_TREMOR -DHAS_ALSA -DHAS_AVAHI -DHAS_DAEMON
|
CXXFLAGS += -pthread -DNO_CPP11_STRING -DHAS_TREMOR -DHAS_ALSA -DHAS_AVAHI -DHAS_DAEMON
|
||||||
LDFLAGS = -lasound -lvorbisidec -logg -lFLAC -lavahi-client -lavahi-common -latomic
|
LDFLAGS = -lasound -lvorbisidec -logg -lFLAC -lavahi-client -lavahi-common -latomic
|
||||||
OBJ += player/alsaPlayer.o browseZeroConf/browseAvahi.o
|
OBJ += ../common/daemon.o player/alsaPlayer.o browseZeroConf/browseAvahi.o
|
||||||
|
|
||||||
else ifeq ($(TARGET), BUILDROOT)
|
else ifeq ($(TARGET), BUILDROOT)
|
||||||
|
|
||||||
CXXFLAGS += -pthread -DNO_CPP11_STRING -DHAS_TREMOR -DHAS_ALSA -DHAS_AVAHI -DHAS_DAEMON
|
CXXFLAGS += -pthread -DNO_CPP11_STRING -DHAS_TREMOR -DHAS_ALSA -DHAS_AVAHI -DHAS_DAEMON
|
||||||
LDFLAGS += -lasound -lvorbisidec -logg -lFLAC -lavahi-client -lavahi-common -latomic
|
LDFLAGS += -lasound -lvorbisidec -logg -lFLAC -lavahi-client -lavahi-common -latomic
|
||||||
OBJ += player/alsaPlayer.o browseZeroConf/browseAvahi.o
|
OBJ += ../common/daemon.o player/alsaPlayer.o browseZeroConf/browseAvahi.o
|
||||||
|
|
||||||
else ifeq ($(TARGET), MACOS)
|
else ifeq ($(TARGET), MACOS)
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ CXX = g++
|
||||||
STRIP = strip
|
STRIP = strip
|
||||||
CXXFLAGS += -DHAS_OGG -DHAS_COREAUDIO -DFREEBSD -DMACOS -DHAS_BONJOUR -DHAS_DAEMON -I/usr/local/include -Wno-unused-local-typedef -Wno-deprecated
|
CXXFLAGS += -DHAS_OGG -DHAS_COREAUDIO -DFREEBSD -DMACOS -DHAS_BONJOUR -DHAS_DAEMON -I/usr/local/include -Wno-unused-local-typedef -Wno-deprecated
|
||||||
LDFLAGS = -logg -lvorbis -lFLAC -L/usr/local/lib -framework AudioToolbox -framework CoreFoundation -framework IOKit
|
LDFLAGS = -logg -lvorbis -lFLAC -L/usr/local/lib -framework AudioToolbox -framework CoreFoundation -framework IOKit
|
||||||
OBJ += player/coreAudioPlayer.o browseZeroConf/browseBonjour.o
|
OBJ += ../common/daemon.o player/coreAudioPlayer.o browseZeroConf/browseBonjour.o
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ CXX = g++
|
||||||
STRIP = strip
|
STRIP = strip
|
||||||
CXXFLAGS += -pthread -DHAS_OGG -DHAS_ALSA -DHAS_AVAHI -DHAS_DAEMON
|
CXXFLAGS += -pthread -DHAS_OGG -DHAS_ALSA -DHAS_AVAHI -DHAS_DAEMON
|
||||||
LDFLAGS = -lrt -lasound -logg -lvorbis -lFLAC -lavahi-client -lavahi-common -static-libgcc -static-libstdc++
|
LDFLAGS = -lrt -lasound -logg -lvorbis -lFLAC -lavahi-client -lavahi-common -static-libgcc -static-libstdc++
|
||||||
OBJ += player/alsaPlayer.o browseZeroConf/browseAvahi.o
|
OBJ += ../common/daemon.o player/alsaPlayer.o browseZeroConf/browseAvahi.o
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ installsysv:
|
||||||
|
|
||||||
adduser:
|
adduser:
|
||||||
@if ! getent passwd snapclient >/dev/null; then \
|
@if ! getent passwd snapclient >/dev/null; then \
|
||||||
useradd --gid audio --system --home-dir /var/lib/snapclient snapclient; \
|
useradd --gid audio --system snapclient; \
|
||||||
fi; \
|
fi; \
|
||||||
|
|
||||||
ifeq ($(TARGET), MACOS)
|
ifeq ($(TARGET), MACOS)
|
||||||
|
|
|
@ -159,9 +159,10 @@ int main (int argc, char **argv)
|
||||||
signal(SIGTERM, signal_handler);
|
signal(SIGTERM, signal_handler);
|
||||||
signal(SIGINT, signal_handler);
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
|
#ifdef HAS_DAEMON
|
||||||
|
std::unique_ptr<Daemon> daemon;
|
||||||
if (daemonOption.isSet())
|
if (daemonOption.isSet())
|
||||||
{
|
{
|
||||||
#ifdef HAS_DAEMON
|
|
||||||
string pidFile = "/var/run/snapclient/pid";
|
string pidFile = "/var/run/snapclient/pid";
|
||||||
if (instance != 1)
|
if (instance != 1)
|
||||||
pidFile += "." + cpt::to_string(instance);
|
pidFile += "." + cpt::to_string(instance);
|
||||||
|
@ -178,7 +179,8 @@ int main (int argc, char **argv)
|
||||||
if (user_group.size() > 1)
|
if (user_group.size() > 1)
|
||||||
group = user_group[1];
|
group = user_group[1];
|
||||||
}
|
}
|
||||||
daemonize(user, group, pidFile);
|
daemon.reset(new Daemon(user, group, pidFile));
|
||||||
|
daemon->daemonize();
|
||||||
if (processPriority < -20)
|
if (processPriority < -20)
|
||||||
processPriority = -20;
|
processPriority = -20;
|
||||||
else if (processPriority > 19)
|
else if (processPriority > 19)
|
||||||
|
@ -186,8 +188,8 @@ int main (int argc, char **argv)
|
||||||
if (processPriority != 0)
|
if (processPriority != 0)
|
||||||
setpriority(PRIO_PROCESS, 0, processPriority);
|
setpriority(PRIO_PROCESS, 0, processPriority);
|
||||||
logS(kLogNotice) << "daemon started" << std::endl;
|
logS(kLogNotice) << "daemon started" << std::endl;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
PcmDevice pcmDevice = getPcmDevice(soundcard);
|
PcmDevice pcmDevice = getPcmDevice(soundcard);
|
||||||
#if defined(HAS_ALSA)
|
#if defined(HAS_ALSA)
|
||||||
|
@ -241,9 +243,6 @@ int main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
logS(kLogNotice) << "daemon terminated." << endl;
|
logS(kLogNotice) << "daemon terminated." << endl;
|
||||||
#ifdef HAS_DAEMON
|
|
||||||
daemonShutdown();
|
|
||||||
#endif
|
|
||||||
exit(exitcode);
|
exit(exitcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
170
common/daemon.cpp
Normal file
170
common/daemon.cpp
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
/***
|
||||||
|
This file is part of snapcast
|
||||||
|
Copyright (C) 2014-2017 Johannes Pohl
|
||||||
|
|
||||||
|
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 3 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.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include "daemon.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include "common/snapException.h"
|
||||||
|
#include "common/strCompat.h"
|
||||||
|
#include "common/utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
Daemon::Daemon(const std::string& user, const std::string& group, const std::string& pidfile) :
|
||||||
|
pidFilehandle_(-1),
|
||||||
|
user_(user),
|
||||||
|
group_(group),
|
||||||
|
pidfile_(pidfile)
|
||||||
|
{
|
||||||
|
if (pidfile.empty() || pidfile.find('/') == std::string::npos)
|
||||||
|
throw SnapException("invalid pid file \"" + pidfile + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Daemon::~Daemon()
|
||||||
|
{
|
||||||
|
if (pidFilehandle_ != -1)
|
||||||
|
close(pidFilehandle_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Daemon::daemonize()
|
||||||
|
{
|
||||||
|
std::string pidfileDir(pidfile_.substr(0, pidfile_.find_last_of('/')));
|
||||||
|
mkdirRecursive(pidfileDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||||
|
|
||||||
|
/// Ensure only one copy
|
||||||
|
pidFilehandle_ = open(pidfile_.c_str(), O_RDWR|O_CREAT, 0644);
|
||||||
|
if (pidFilehandle_ == -1 )
|
||||||
|
{
|
||||||
|
/// Couldn't open lock file
|
||||||
|
throw SnapException("Could not open PID lock file \"" + pidfile_ + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
uid_t user_uid = (uid_t)-1;
|
||||||
|
gid_t user_gid = (gid_t)-1;
|
||||||
|
std::string user_name;
|
||||||
|
#ifdef FREEBSD
|
||||||
|
bool had_group = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!user_.empty())
|
||||||
|
{
|
||||||
|
struct passwd *pwd = getpwnam(user_.c_str());
|
||||||
|
if (pwd == nullptr)
|
||||||
|
throw SnapException("no such user \"" + user_ + "\"");
|
||||||
|
user_uid = pwd->pw_uid;
|
||||||
|
user_gid = pwd->pw_gid;
|
||||||
|
user_name = strdup(user_.c_str());
|
||||||
|
/// this is needed by libs such as arts
|
||||||
|
setenv("HOME", pwd->pw_dir, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!group_.empty())
|
||||||
|
{
|
||||||
|
struct group *grp = getgrnam(group_.c_str());
|
||||||
|
if (grp == nullptr)
|
||||||
|
throw SnapException("no such group \"" + group_ + "\"");
|
||||||
|
user_gid = grp->gr_gid;
|
||||||
|
#ifdef FREEBSD
|
||||||
|
had_group = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chown(pidfile_.c_str(), user_uid, user_gid) == -1)
|
||||||
|
{
|
||||||
|
/// Couldn't open lock file
|
||||||
|
throw SnapException("Could not chown PID lock file \"" + pidfile_ + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// set gid
|
||||||
|
if (user_gid != (gid_t)-1 && user_gid != getgid() && setgid(user_gid) == -1)
|
||||||
|
throw SnapException("Failed to set group " + cpt::to_string((int)user_gid));
|
||||||
|
|
||||||
|
//#if defined(FREEBSD) && !defined(MACOS)
|
||||||
|
//#ifdef FREEBSD
|
||||||
|
/// init supplementary groups
|
||||||
|
/// (must be done before we change our uid)
|
||||||
|
/// no need to set the new user's supplementary groups if we are already this user
|
||||||
|
// if (!had_group && user_uid != getuid() && initgroups(user_name, user_gid) == -1)
|
||||||
|
// throw SnapException("Failed to set supplementary groups of user \"" + user + "\"");
|
||||||
|
//#endif
|
||||||
|
/// set uid
|
||||||
|
if (user_uid != (uid_t)-1 && user_uid != getuid() && setuid(user_uid) == -1)
|
||||||
|
throw SnapException("Failed to set user " + user_);
|
||||||
|
|
||||||
|
/// Our process ID and Session ID
|
||||||
|
pid_t pid, sid;
|
||||||
|
|
||||||
|
/// Fork off the parent process
|
||||||
|
pid = fork();
|
||||||
|
if (pid < 0)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
/// If we got a good PID, then we can exit the parent process.
|
||||||
|
if (pid > 0)
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
|
||||||
|
/// Change the file mode mask
|
||||||
|
umask(0);
|
||||||
|
|
||||||
|
/// Open any logs here
|
||||||
|
|
||||||
|
/// Create a new SID for the child process
|
||||||
|
sid = setsid();
|
||||||
|
if (sid < 0)
|
||||||
|
{
|
||||||
|
/// Log the failure
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Change the current working directory
|
||||||
|
if ((chdir("/")) < 0)
|
||||||
|
{
|
||||||
|
/// Log the failure
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Try to lock file
|
||||||
|
if (lockf(pidFilehandle_, F_TLOCK, 0) == -1)
|
||||||
|
throw SnapException("Could not lock PID lock file \"" + pidfile_ + "\"");
|
||||||
|
|
||||||
|
char str[10];
|
||||||
|
/// Get and format PID
|
||||||
|
sprintf(str, "%d\n", getpid());
|
||||||
|
|
||||||
|
/// write pid to lockfile
|
||||||
|
if (write(pidFilehandle_, str, strlen(str)) != (int)strlen(str))
|
||||||
|
throw SnapException("Could not write PID to lock file \"" + pidfile_ + "\"");
|
||||||
|
|
||||||
|
/// Close out the standard file descriptors
|
||||||
|
close(STDIN_FILENO);
|
||||||
|
close(STDOUT_FILENO);
|
||||||
|
close(STDERR_FILENO);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
153
common/daemon.h
153
common/daemon.h
|
@ -16,149 +16,26 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#ifndef DAEMONIZE_H
|
#ifndef DAEMON_H
|
||||||
#define DAEMONIZE_H
|
#define DAEMON_H
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <string>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <grp.h>
|
|
||||||
#include "common/snapException.h"
|
|
||||||
#include "common/strCompat.h"
|
|
||||||
#include "common/utils.h"
|
|
||||||
|
|
||||||
|
|
||||||
int pidFilehandle;
|
class Daemon
|
||||||
|
|
||||||
void daemonize(const std::string& user, const std::string& group, const std::string& pidfile)
|
|
||||||
{
|
{
|
||||||
if (pidfile.empty() || pidfile.find('/') == std::string::npos)
|
public:
|
||||||
throw SnapException("invalid pid file \"" + pidfile + "\"");
|
Daemon(const std::string& user, const std::string& group, const std::string& pidfile);
|
||||||
|
virtual ~Daemon();
|
||||||
|
|
||||||
std::string pidfileDir(pidfile.substr(0, pidfile.find_last_of('/')));
|
void daemonize();
|
||||||
mkdirRecursive(pidfileDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
|
||||||
|
|
||||||
/// Ensure only one copy
|
private:
|
||||||
pidFilehandle = open(pidfile.c_str(), O_RDWR|O_CREAT, 0644);
|
int pidFilehandle_;
|
||||||
if (pidFilehandle == -1 )
|
std::string user_;
|
||||||
{
|
std::string group_;
|
||||||
/// Couldn't open lock file
|
std::string pidfile_;
|
||||||
throw SnapException("Could not open PID lock file \"" + pidfile + "\"");
|
};
|
||||||
}
|
|
||||||
|
|
||||||
uid_t user_uid = (uid_t)-1;
|
|
||||||
gid_t user_gid = (gid_t)-1;
|
|
||||||
std::string user_name;
|
|
||||||
#ifdef FREEBSD
|
|
||||||
bool had_group = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!user.empty())
|
|
||||||
{
|
|
||||||
struct passwd *pwd = getpwnam(user.c_str());
|
|
||||||
if (pwd == nullptr)
|
|
||||||
throw SnapException("no such user \"" + user + "\"");
|
|
||||||
user_uid = pwd->pw_uid;
|
|
||||||
user_gid = pwd->pw_gid;
|
|
||||||
user_name = strdup(user.c_str());
|
|
||||||
/// this is needed by libs such as arts
|
|
||||||
setenv("HOME", pwd->pw_dir, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!group.empty()) {
|
|
||||||
struct group *grp = getgrnam(group.c_str());
|
|
||||||
if (grp == nullptr)
|
|
||||||
throw SnapException("no such group \"" + group + "\"");
|
|
||||||
user_gid = grp->gr_gid;
|
|
||||||
#ifdef FREEBSD
|
|
||||||
had_group = true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chown(pidfile.c_str(), user_uid, user_gid) == -1)
|
|
||||||
{
|
|
||||||
/// Couldn't open lock file
|
|
||||||
throw SnapException("Could not chown PID lock file \"" + pidfile + "\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// set gid
|
|
||||||
if (user_gid != (gid_t)-1 && user_gid != getgid() && setgid(user_gid) == -1)
|
|
||||||
throw SnapException("Failed to set group " + cpt::to_string((int)user_gid));
|
|
||||||
|
|
||||||
//#if defined(FREEBSD) && !defined(MACOS)
|
|
||||||
//#ifdef FREEBSD
|
|
||||||
/// init supplementary groups
|
|
||||||
/// (must be done before we change our uid)
|
|
||||||
/// no need to set the new user's supplementary groups if we are already this user
|
|
||||||
// if (!had_group && user_uid != getuid() && initgroups(user_name, user_gid) == -1)
|
|
||||||
// throw SnapException("Failed to set supplementary groups of user \"" + user + "\"");
|
|
||||||
//#endif
|
|
||||||
/// set uid
|
|
||||||
if (user_uid != (uid_t)-1 && user_uid != getuid() && setuid(user_uid) == -1)
|
|
||||||
throw SnapException("Failed to set user " + user);
|
|
||||||
|
|
||||||
/// Our process ID and Session ID
|
|
||||||
pid_t pid, sid;
|
|
||||||
|
|
||||||
/// Fork off the parent process
|
|
||||||
pid = fork();
|
|
||||||
if (pid < 0)
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
/// If we got a good PID, then we can exit the parent process.
|
|
||||||
if (pid > 0)
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
|
|
||||||
/// Change the file mode mask
|
|
||||||
umask(0);
|
|
||||||
|
|
||||||
/// Open any logs here
|
|
||||||
|
|
||||||
/// Create a new SID for the child process
|
|
||||||
sid = setsid();
|
|
||||||
if (sid < 0)
|
|
||||||
{
|
|
||||||
/// Log the failure
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Change the current working directory
|
|
||||||
if ((chdir("/")) < 0)
|
|
||||||
{
|
|
||||||
/// Log the failure
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Try to lock file
|
|
||||||
if (lockf(pidFilehandle, F_TLOCK, 0) == -1)
|
|
||||||
throw SnapException("Could not lock PID lock file \"" + pidfile + "\"");
|
|
||||||
|
|
||||||
char str[10];
|
|
||||||
/// Get and format PID
|
|
||||||
sprintf(str, "%d\n", getpid());
|
|
||||||
|
|
||||||
/// write pid to lockfile
|
|
||||||
if (write(pidFilehandle, str, strlen(str)) != (int)strlen(str))
|
|
||||||
throw SnapException("Could not write PID to lock file \"" + pidfile + "\"");
|
|
||||||
|
|
||||||
/// Close out the standard file descriptors
|
|
||||||
close(STDIN_FILENO);
|
|
||||||
close(STDOUT_FILENO);
|
|
||||||
close(STDERR_FILENO);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void daemonShutdown()
|
|
||||||
{
|
|
||||||
close(pidFilehandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // DAEMON_H
|
||||||
|
|
|
@ -50,7 +50,7 @@ else ifeq ($(TARGET), OPENWRT)
|
||||||
STRIP = echo
|
STRIP = echo
|
||||||
CXXFLAGS += -DNO_CPP11_STRING -DHAS_AVAHI -DHAS_DAEMON -pthread
|
CXXFLAGS += -DNO_CPP11_STRING -DHAS_AVAHI -DHAS_DAEMON -pthread
|
||||||
LDFLAGS += -lavahi-client -lavahi-common -latomic
|
LDFLAGS += -lavahi-client -lavahi-common -latomic
|
||||||
OBJ += publishZeroConf/publishAvahi.o
|
OBJ += ../common/daemon.o publishZeroConf/publishAvahi.o
|
||||||
|
|
||||||
else ifeq ($(TARGET), FREEBSD)
|
else ifeq ($(TARGET), FREEBSD)
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ CXX = g++
|
||||||
STRIP = echo
|
STRIP = echo
|
||||||
CXXFLAGS += -DNO_CPP11_STRING -DFREEBSD -DHAS_AVAHI -DHAS_DAEMON -pthread
|
CXXFLAGS += -DNO_CPP11_STRING -DFREEBSD -DHAS_AVAHI -DHAS_DAEMON -pthread
|
||||||
LDFLAGS += -lrt -lavahi-client -lavahi-common -static-libgcc -static-libstdc++
|
LDFLAGS += -lrt -lavahi-client -lavahi-common -static-libgcc -static-libstdc++
|
||||||
OBJ += publishZeroConf/publishAvahi.o
|
OBJ += ../common/daemon.o publishZeroConf/publishAvahi.o
|
||||||
|
|
||||||
else ifeq ($(TARGET), MACOS)
|
else ifeq ($(TARGET), MACOS)
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ CXX = g++
|
||||||
STRIP = strip
|
STRIP = strip
|
||||||
CXXFLAGS += -DFREEBSD -DMACOS -DHAS_BONJOUR -DHAS_DAEMON -Wno-deprecated -I/usr/local/include
|
CXXFLAGS += -DFREEBSD -DMACOS -DHAS_BONJOUR -DHAS_DAEMON -Wno-deprecated -I/usr/local/include
|
||||||
LDFLAGS += -L/usr/local/lib -framework CoreFoundation -framework IOKit
|
LDFLAGS += -L/usr/local/lib -framework CoreFoundation -framework IOKit
|
||||||
OBJ += publishZeroConf/publishBonjour.o
|
OBJ += ../common/daemon.o publishZeroConf/publishBonjour.o
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ CXX = g++
|
||||||
STRIP = strip
|
STRIP = strip
|
||||||
CXXFLAGS += -DHAS_AVAHI -DHAS_DAEMON -pthread
|
CXXFLAGS += -DHAS_AVAHI -DHAS_DAEMON -pthread
|
||||||
LDFLAGS = -lrt -lvorbis -lvorbisenc -logg -lFLAC -lavahi-client -lavahi-common -static-libgcc -static-libstdc++
|
LDFLAGS = -lrt -lvorbis -lvorbisenc -logg -lFLAC -lavahi-client -lavahi-common -static-libgcc -static-libstdc++
|
||||||
OBJ += publishZeroConf/publishAvahi.o
|
OBJ += ../common/daemon.o publishZeroConf/publishAvahi.o
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include "common/snapException.h"
|
#include "common/snapException.h"
|
||||||
|
@ -34,13 +35,30 @@ Config::Config()
|
||||||
if (getenv("HOME") == NULL)
|
if (getenv("HOME") == NULL)
|
||||||
dir = "/var/lib/snapserver/";
|
dir = "/var/lib/snapserver/";
|
||||||
else
|
else
|
||||||
dir = getenv("HOME") + string("/.config/snapserver/");
|
dir = getenv("HOME");
|
||||||
|
|
||||||
|
if (!dir.empty() && (dir.back() != '/'))
|
||||||
|
dir += "/";
|
||||||
|
|
||||||
|
if (dir.find("/var/lib/snapserver") == string::npos)
|
||||||
|
dir += ".config/snapserver/";
|
||||||
|
|
||||||
int status = mkdirRecursive(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
int status = mkdirRecursive(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||||
if ((status != 0) && (errno != EEXIST))
|
if ((status != 0) && (errno != EEXIST))
|
||||||
throw SnapException("failed to create settings directory: \"" + dir + "\": " + cpt::to_string(errno));
|
throw SnapException("failed to create settings directory: \"" + dir + "\": " + cpt::to_string(errno));
|
||||||
|
|
||||||
filename_ = dir + "server.json";
|
filename_ = dir + "server.json";
|
||||||
logO << "Settings file: " << filename_ << "\n";
|
logS(kLogNotice) << "Settings file: \"" << filename_ << "\"\n";
|
||||||
|
|
||||||
|
int fd;
|
||||||
|
if ((fd = open(filename_.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
|
||||||
|
{
|
||||||
|
if (errno == EACCES)
|
||||||
|
throw std::runtime_error("failed to open file \"" + filename_ + "\", permission denied");
|
||||||
|
else
|
||||||
|
throw std::runtime_error("failed to open file \"" + filename_ + "\"");
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,6 +51,7 @@ int main(int argc, char* argv[])
|
||||||
#ifdef MACOS
|
#ifdef MACOS
|
||||||
#pragma message "Warning: the macOS support is experimental and might not be maintained"
|
#pragma message "Warning: the macOS support is experimental and might not be maintained"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int exitcode = EXIT_SUCCESS;
|
int exitcode = EXIT_SUCCESS;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -140,16 +141,16 @@ int main(int argc, char* argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::instance();
|
|
||||||
std::clog.rdbuf(new Log("snapserver", LOG_DAEMON));
|
std::clog.rdbuf(new Log("snapserver", LOG_DAEMON));
|
||||||
|
|
||||||
signal(SIGHUP, signal_handler);
|
signal(SIGHUP, signal_handler);
|
||||||
signal(SIGTERM, signal_handler);
|
signal(SIGTERM, signal_handler);
|
||||||
signal(SIGINT, signal_handler);
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
|
#ifdef HAS_DAEMON
|
||||||
|
std::unique_ptr<Daemon> daemon;
|
||||||
if (daemonOption.isSet())
|
if (daemonOption.isSet())
|
||||||
{
|
{
|
||||||
#ifdef HAS_DAEMON
|
|
||||||
string user = "";
|
string user = "";
|
||||||
string group = "";
|
string group = "";
|
||||||
|
|
||||||
|
@ -163,7 +164,9 @@ int main(int argc, char* argv[])
|
||||||
if (user_group.size() > 1)
|
if (user_group.size() > 1)
|
||||||
group = user_group[1];
|
group = user_group[1];
|
||||||
}
|
}
|
||||||
daemonize(user, group, "/var/run/snapserver/pid");
|
|
||||||
|
daemon.reset(new Daemon(user, group, "/var/run/snapserver/pid"));
|
||||||
|
daemon->daemonize();
|
||||||
if (processPriority < -20)
|
if (processPriority < -20)
|
||||||
processPriority = -20;
|
processPriority = -20;
|
||||||
else if (processPriority > 19)
|
else if (processPriority > 19)
|
||||||
|
@ -171,8 +174,11 @@ int main(int argc, char* argv[])
|
||||||
if (processPriority != 0)
|
if (processPriority != 0)
|
||||||
setpriority(PRIO_PROCESS, 0, processPriority);
|
setpriority(PRIO_PROCESS, 0, processPriority);
|
||||||
logS(kLogNotice) << "daemon started" << std::endl;
|
logS(kLogNotice) << "daemon started" << std::endl;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Config::instance();
|
||||||
|
|
||||||
#if defined(HAS_AVAHI) || defined(HAS_BONJOUR)
|
#if defined(HAS_AVAHI) || defined(HAS_BONJOUR)
|
||||||
PublishZeroConf publishZeroConfg("Snapcast");
|
PublishZeroConf publishZeroConfg("Snapcast");
|
||||||
publishZeroConfg.publish({mDNSService("_snapcast._tcp", settings.port), mDNSService("_snapcast-jsonrpc._tcp", settings.controlPort)});
|
publishZeroConfg.publish({mDNSService("_snapcast._tcp", settings.port), mDNSService("_snapcast-jsonrpc._tcp", settings.controlPort)});
|
||||||
|
@ -206,9 +212,6 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
logS(kLogNotice) << "daemon terminated." << endl;
|
logS(kLogNotice) << "daemon terminated." << endl;
|
||||||
#ifdef HAS_DAEMON
|
|
||||||
daemonShutdown();
|
|
||||||
#endif
|
|
||||||
exit(exitcode);
|
exit(exitcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue