|
@@ -17,6 +17,8 @@
|
|
|
import os
|
|
|
import sys
|
|
|
|
|
|
+from jwmudlib import jwmu_exceptions
|
|
|
+
|
|
|
|
|
|
class Daemon(object):
|
|
|
""" Tries to implement a well behaving unix daemon in a generic way,
|
|
@@ -30,7 +32,6 @@ class Daemon(object):
|
|
|
self.__pfile_name = pfile_name
|
|
|
self.__daemon = False
|
|
|
self.__pid = 0
|
|
|
- self.__pidfile = ""
|
|
|
|
|
|
def Daemonize(self):
|
|
|
""" Turns the calling process into a daemon running on it's own """
|
|
@@ -71,44 +72,52 @@ class Daemon(object):
|
|
|
|
|
|
self.__daemon = True
|
|
|
|
|
|
- def DropPriv(self, uid, gid):
|
|
|
+ def DropPrivileges(self, user, group):
|
|
|
""" If the daemon is running as root user, drop privileges and continue
|
|
|
- running as the defined unprivileged user """
|
|
|
- if os.getuid() == 0:
|
|
|
- os.setgid(gid)
|
|
|
- os.setuid(uid)
|
|
|
-
|
|
|
- def SetName(self, name, cmdline):
|
|
|
- """ Sets the name of the process shown visible in ps and top,
|
|
|
- this allows to make your daemon look more like a standalone
|
|
|
- program instead of a python script.
|
|
|
+ running as the defined unprivileged user.
|
|
|
|
|
|
"""
|
|
|
+ pid_file_path = os.path.join(self.__pfile_path, self.__pfile_name)
|
|
|
try:
|
|
|
- # First check if prctl is available, otherwise this
|
|
|
- # function does nothing
|
|
|
- # noinspection PyUnresolvedReferences
|
|
|
- import prctl
|
|
|
- except ImportError:
|
|
|
- return False
|
|
|
+ passwd_file = open("/etc/passwd", "r")
|
|
|
+ group_file = open("/etc/group", "r")
|
|
|
+ except PermissionError:
|
|
|
+ raise jwmu_exceptions.PasswdOrGroupAccessFailed()
|
|
|
else:
|
|
|
- prctl.set_name(name)
|
|
|
- prctl.set_proctitle(cmdline)
|
|
|
- return True
|
|
|
+ uid = ""
|
|
|
+ gid = ""
|
|
|
+ for line in passwd_file:
|
|
|
+ if user in line:
|
|
|
+ uid = line.split(":")[2]
|
|
|
+ break
|
|
|
+ for line in group_file:
|
|
|
+ if group in line.split(":")[0]:
|
|
|
+ gid = line.split(":")[2]
|
|
|
+ break
|
|
|
+ passwd_file.close()
|
|
|
+ group_file.close()
|
|
|
+ if os.getuid() == 0:
|
|
|
+ os.chown(pid_file_path, int(uid), int(gid))
|
|
|
+ os.setgid(int(gid))
|
|
|
+ os.setuid(int(uid))
|
|
|
|
|
|
def Start(self):
|
|
|
""" Performs the operations needed to "start" the daemon """
|
|
|
+ pid_file_path = os.path.join(self.__pfile_path, self.__pfile_name)
|
|
|
+ if os.access(pid_file_path, os.F_OK):
|
|
|
+ old_pid_file = open(pid_file_path, "r")
|
|
|
+ old_pid = old_pid_file.read().strip()
|
|
|
+ old_pid_file.close()
|
|
|
+ if os.access(os.path.join("/proc/", old_pid), os.F_OK):
|
|
|
+ raise jwmu_exceptions.DaemonAlreadyRunning()
|
|
|
if self.__daemon is True:
|
|
|
- if os.access(self.__pfile_path, os.F_OK & os.W_OK):
|
|
|
- self.__pidfile = open(os.path.join(self.__pfile_path,
|
|
|
- self.__pfile_name), "w")
|
|
|
- self.__pidfile.write(str(os.getpid()) + "\n")
|
|
|
- self.__pidfile.close()
|
|
|
- return True
|
|
|
+ try:
|
|
|
+ pid_file = open(pid_file_path, "w")
|
|
|
+ except IOError:
|
|
|
+ raise jwmu_exceptions.WritingPIDFileFailed()
|
|
|
else:
|
|
|
- return False
|
|
|
- else:
|
|
|
- return False
|
|
|
+ pid_file.write(str(os.getpid()) + "\n")
|
|
|
+ pid_file.close()
|
|
|
|
|
|
def Stop(self):
|
|
|
""" Performs the operations needed to stop the daemon """
|