diff --git a/.gitignore b/.gitignore
index 874f86a..6f4050f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,7 +2,6 @@
 pykms_logserver.log*
 pykms_logclient.log*
 pykms_database.db*
-etrigan.log*
 
 # Byte-compiled / optimized / DLL files
 __pycache__/
diff --git a/docs/Getting Started.md b/docs/Getting Started.md
index 6669c26..129a674 100644
--- a/docs/Getting Started.md	
+++ b/docs/Getting Started.md	
@@ -91,10 +91,6 @@ Check syntax with `sudo systemd-analyze verify py3-kms.service`, correct file pe
 start the daemon `sudo systemctl start py3-kms.service` and view its status `sudo systemctl status py3-kms.service`. Check if daemon is correctly running with `cat </path/to/your/log/files/folder>/pykms_logserver.log`. Finally a
 few generic commands useful for interact with your daemon [here](https://linoxide.com/linux-how-to/enable-disable-services-ubuntu-systemd-upstart/).
 
-### Etrigan (deprecated)
-You can run py-kms daemonized (via [Etrigan](https://github.com/SystemRage/Etrigan)) using a command like `python3 pykms_Server.py etrigan start` and stop it with `python3 pykms_Server.py etrigan stop`. With Etrigan you have another
-way to launch py-kms GUI (specially suitable if you're using a virtualenv), so `python3 pykms_Server.py etrigan start -g` and stop the GUI with `python3 pykms_Server.py etrigan stop` (or interact with the `EXIT` button).
-
 ### Upstart (deprecated)
 If you are running a Linux distro using `upstart` (deprecated), create the file: `sudo nano /etc/init/py3-kms.conf`, then add the following (change it where needed) and save:
 ```
diff --git a/py-kms/Etrigan.py b/py-kms/Etrigan.py
deleted file mode 100644
index c9cf193..0000000
--- a/py-kms/Etrigan.py
+++ /dev/null
@@ -1,609 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
-import atexit
-import errno
-import os
-import sys
-import time
-import signal
-import logging
-import argparse
-from collections.abc import Sequence
-
-__version__             = "0.1"
-__license__             = "MIT License"
-__author__              = u"Matteo ℱan <SystemRage@protonmail.com>"
-__copyright__           = "© Copyright 2020"
-__url__                 = "https://github.com/SystemRage/Etrigan"
-__description__         = "Etrigan: a python daemonizer that rocks."
-
-
-class Etrigan(object):
-        """
-        Daemonizer based on double-fork method
-        --------------------------------------
-        Each option can be passed as a keyword argument or modified by assigning
-        to an attribute on the instance:
-        
-        jasonblood = Etrigan(pidfile,
-                             argument_example_1 = foo,
-                             argument_example_2 = bar)
-        
-        that is equivalent to:
-        
-        jasonblood = Etrigan(pidfile)
-        jasonblood.argument_example_1 = foo
-        jasonblood.argument_example_2 = bar
-
-        Object constructor expects always `pidfile` argument.
-        `pidfile`
-                Path to the pidfile.
-        
-        The following other options are defined:
-        `stdin`
-        `stdout`
-        `stderr`
-                :Default: `os.devnull`
-                        File objects used as the new file for the standard I/O streams
-                        `sys.stdin`, `sys.stdout`, and `sys.stderr` respectively.
-                        
-        `funcs_to_daemonize`
-                :Default: `[]`
-                        Define a list of your custom functions
-                        which will be executed after daemonization.
-                        If None, you have to subclass Etrigan `run` method.
-                        Note that these functions can return elements that will be
-                        added to Etrigan object (`etrigan_add` list) so the other subsequent
-                        ones can reuse them for further processing.
-                        You only have to provide indexes of `etrigan_add` list,
-                        (an int (example: 2) for single index or a string (example: '1:4') for slices)
-                        as first returning element.
-
-        `want_quit`
-                :Default: `False`
-                        If `True`, runs Etrigan `quit_on_start` or `quit_on_stop`
-                        lists of your custom functions at the end of `start` or `stop` operations.
-                        These can return elements as `funcs_to_daemonize`.
-
-        `logfile`
-                :Default: `None`
-                        Path to the output log file.
-
-        `loglevel`
-                :Default: `None`
-                        Set the log level of logging messages.
-
-        `mute`
-                :Default: `False`
-                        Disable all stdout and stderr messages (before double forking).
-
-        `pause_loop`
-                :Default: `None`
-                        Seconds of pause between the calling, in an infinite loop,
-                        of every function in `funcs_to_daemonize` list.
-                        If `-1`, no pause between the calling, in an infinite loop,
-                        of every function in `funcs_to_daemonize` list.                   
-                        If `None`, only one run (no infinite loop) of functions in
-                        `funcs_to_daemonize` list, without pause.       
-        """
-        
-        def __init__(self, pidfile,
-                     stdin = os.devnull, stdout = os.devnull, stderr = os.devnull,
-                     funcs_to_daemonize = [], want_quit = False,
-                     logfile = None, loglevel = None,
-                     mute = False, pause_loop = None):
-
-                self.pidfile = pidfile                
-                self.funcs_to_daemonize = funcs_to_daemonize
-                self.stdin = stdin
-                self.stdout = stdout
-                self.stderr = stderr
-                self.logfile = logfile
-                self.loglevel = loglevel
-                self.mute = mute
-                self.want_quit = want_quit
-                self.pause_loop = pause_loop
-                # internal only.               
-                self.homedir = '/'
-                self.umask = 0o22
-                self.etrigan_restart, self.etrigan_reload = (False for _ in range(2))
-                self.etrigan_alive = True
-                self.etrigan_add = []
-                self.etrigan_index = None
-                # seconds of pause between stop and start during the restart of the daemon.
-                self.pause_restart = 5
-                # when terminate a process, seconds to wait until kill the process with signal.
-                # self.pause_kill = 3
-                
-                # create logfile.
-                self.setup_files()
-
-        def handle_terminate(self, signum, frame):
-                if os.path.exists(self.pidfile):
-                        self.etrigan_alive = False
-                        # eventually run quit (on stop) function/s.
-                        if self.want_quit:
-                                if not isinstance(self.quit_on_stop, (list, tuple)):
-                                        self.quit_on_stop = [self.quit_on_stop]
-                                self.execute(self.quit_on_stop)
-                        # then always run quit standard.
-                        self.quit_standard()
-                else:
-                        self.view(self.logdaemon.error, self.emit_error, "Failed to stop the daemon process: can't find PIDFILE '%s'" %self.pidfile)
-                sys.exit(0)
-
-        def handle_reload(self, signum, frame):
-                self.etrigan_reload = True
-
-        def setup_files(self):
-                self.pidfile = os.path.abspath(self.pidfile)
-                
-                if self.logfile is not None:                     
-                        self.logdaemon = logging.getLogger('logdaemon')
-                        self.logdaemon.setLevel(self.loglevel)
-                        
-                        filehandler = logging.FileHandler(self.logfile)
-                        filehandler.setLevel(self.loglevel)
-                        formatter = logging.Formatter(fmt = '[%(asctime)s] [%(levelname)8s] --- %(message)s',
-                                                      datefmt = '%Y-%m-%d %H:%M:%S')
-                        filehandler.setFormatter(formatter)
-                        self.logdaemon.addHandler(filehandler)
-                else:
-                        nullhandler = logging.NullHandler()
-                        self.logdaemon.addHandler(nullhandler)
-
-        def emit_error(self, message, to_exit = True):
-                """ Print an error message to STDERR. """
-                if not self.mute:
-                        sys.stderr.write(message + '\n')
-                        sys.stderr.flush()
-                if to_exit:
-                        sys.exit(1)
-
-        def emit_message(self, message, to_exit = False):
-                """ Print a message to STDOUT. """
-                if not self.mute:
-                        sys.stdout.write(message + '\n')
-                        sys.stdout.flush()
-                if to_exit:
-                        sys.exit(0)
-
-        def view(self, logobj, emitobj, msg, **kwargs):
-                options = {'to_exit' : False,
-                           'silent' : False
-                           }
-                options.update(kwargs)
-
-                if logobj:
-                        logobj(msg)
-                if emitobj:                        
-                        if not options['silent']:
-                                emitobj(msg, to_exit = options['to_exit'])
-
-        def daemonize(self):
-                """
-                Double-forks the process to daemonize the script.
-                see Stevens' "Advanced Programming in the UNIX Environment" for details (ISBN 0201563177)
-                http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
-                """
-                self.view(self.logdaemon.debug, None, "Attempting to daemonize the process...")
-
-                # First fork.
-                self.fork(msg = "First fork")
-                # Decouple from parent environment.
-                self.detach()                
-                # Second fork.
-                self.fork(msg = "Second fork")
-                # Write the PID file.
-                self.create_pidfile()
-                self.view(self.logdaemon.info, self.emit_message, "The daemon process has started.")
-                # Redirect standard file descriptors.
-                sys.stdout.flush()
-                sys.stderr.flush()
-                self.attach('stdin', mode = 'r')
-                self.attach('stdout', mode = 'a+')
-
-                try:
-                        self.attach('stderr', mode = 'a+', buffering = 0)
-                except ValueError:
-                        # Python 3 can't have unbuffered text I/O.
-                        self.attach('stderr', mode = 'a+', buffering = 1)
-
-                # Handle signals.                
-                signal.signal(signal.SIGINT, self.handle_terminate)
-                signal.signal(signal.SIGTERM, self.handle_terminate) 
-                signal.signal(signal.SIGHUP, self.handle_reload)
-                #signal.signal(signal.SIGKILL....)
-
-        def fork(self, msg):
-                try:
-                        pid = os.fork()
-                        if pid > 0:                                
-                                self.view(self.logdaemon.debug, None, msg + " success with PID %d." %pid)
-                                # Exit from parent.
-                                sys.exit(0)
-                except Exception as e:
-                        msg += " failed: %s." %str(e)
-                        self.view(self.logdaemon.error, self.emit_error, msg)
-                        
-        def detach(self):
-                # cd to root for a guarenteed working dir.
-                try:
-                        os.chdir(self.homedir)
-                except Exception as e:
-                        msg = "Unable to change working directory: %s." %str(e)
-                        self.view(self.logdaemon.error, self.emit_error, msg)
-                        
-                # clear the session id to clear the controlling tty.
-                pid = os.setsid()
-                if pid == -1:
-                        sys.exit(1)
-                
-                # set the umask so we have access to all files created by the daemon.
-                try:
-                        os.umask(self.umask)
-                except Exception as e:
-                        msg = "Unable to change file creation mask: %s." %str(e)
-                        self.view(self.logdaemon.error, self.emit_error, msg)
-
-        def attach(self, name, mode, buffering = -1):
-                with open(getattr(self, name), mode, buffering) as stream:
-                        os.dup2(stream.fileno(), getattr(sys, name).fileno())
-
-        def checkfile(self, path, typearg, typefile):
-                filename = os.path.basename(path)
-                pathname = os.path.dirname(path)
-                if not os.path.isdir(pathname):
-                        msg = "argument %s: invalid directory: '%s'. Exiting..." %(typearg, pathname)
-                        self.view(self.logdaemon.error, self.emit_error, msg)
-                elif not filename.lower().endswith(typefile):
-                        msg = "argument %s: not a %s file, invalid extension: '%s'. Exiting..." %(typearg, typefile, filename)
-                        self.view(self.logdaemon.error, self.emit_error, msg)
-
-        def create_pidfile(self):
-                atexit.register(self.delete_pidfile)
-                pid = os.getpid()
-                try:
-                        with open(self.pidfile, 'w+') as pf:
-                             pf.write("%s\n" %pid)
-                        self.view(self.logdaemon.debug, None, "PID %d written to '%s'." %(pid, self.pidfile))
-                except Exception as e:
-                        msg = "Unable to write PID to PIDFILE '%s': %s" %(self.pidfile, str(e))
-                        self.view(self.logdaemon.error, self.emit_error, msg)
-
-        def delete_pidfile(self, pid):
-                # Remove the PID file.
-                try:
-                        os.remove(self.pidfile)
-                        self.view(self.logdaemon.debug, None, "Removing PIDFILE '%s' with PID %d." %(self.pidfile, pid))
-                except Exception as e:
-                        if e.errno != errno.ENOENT:
-                                self.view(self.logdaemon.error, self.emit_error, str(e))
-
-        def get_pidfile(self):
-                # Get the PID from the PID file.
-                if self.pidfile is None:
-                        return None
-                if not os.path.isfile(self.pidfile):
-                        return None
-
-                try:
-                        with open(self.pidfile, 'r') as pf:
-                                pid = int(pf.read().strip())
-                        self.view(self.logdaemon.debug, None, "Found PID %d in PIDFILE '%s'" %(pid, self.pidfile))
-                except Exception as e:
-                        self.view(self.logdaemon.warning, None, "Empty or broken PIDFILE")
-                        pid = None
-
-                def pid_exists(pid):
-                        # psutil _psposix.py.
-                        if pid == 0:
-                                return True
-                        try:
-                                os.kill(pid, 0)
-                        except OSError as e:
-                                if e.errno == errno.ESRCH:
-                                        return False
-                                elif e.errno == errno.EPERM:
-                                        return True
-                                else:
-                                        self.view(self.logdaemon.error, self.emit_error, str(e))
-                        else:
-                                return True
-
-                if pid is not None and pid_exists(pid):
-                        return pid
-                else:
-                        # Remove the stale PID file.
-                        self.delete_pidfile(pid)
-                        return None
-
-        def start(self):
-                """ Start the daemon. """
-                self.view(self.logdaemon.info, self.emit_message, "Starting the daemon process...", silent = self.etrigan_restart)
-                
-                # Check for a PID file to see if the Daemon is already running.
-                pid = self.get_pidfile()
-                if pid is not None:
-                        msg = "A previous daemon process with PIDFILE '%s' already exists. Daemon already running ?" %self.pidfile
-                        self.view(self.logdaemon.warning, self.emit_error, msg, to_exit = False)
-                        return
-
-                # Daemonize the main process.
-                self.daemonize()
-                # Start a infinitive loop that periodically runs `funcs_to_daemonize`.
-                self.loop()
-                # eventualy run quit (on start) function/s.
-                if self.want_quit:
-                        if not isinstance(self.quit_on_start, (list, tuple)):
-                                self.quit_on_start = [self.quit_on_start]
-                        self.execute(self.quit_on_start)
-
-        def stop(self):
-                """ Stop the daemon. """
-                self.view(None, self.emit_message, "Stopping the daemon process...", silent = self.etrigan_restart)
-                
-                self.logdaemon.disabled = True
-                pid = self.get_pidfile()
-                self.logdaemon.disabled = False
-                if not pid:
-                        # Just to be sure. A ValueError might occur
-                        # if the PIDFILE is empty but does actually exist.
-                        if os.path.exists(self.pidfile):
-                                self.delete_pidfile(pid)
-
-                        msg = "Can't find the daemon process with PIDFILE '%s'. Daemon not running ?" %self.pidfile
-                        self.view(self.logdaemon.warning, self.emit_error, msg, to_exit = False)
-                        return
-
-                # Try to kill the daemon process.
-                try:
-                        while True:
-                                os.kill(pid, signal.SIGTERM)
-                                time.sleep(0.1)
-                except Exception as e:
-                        if (e.errno != errno.ESRCH):
-                                self.view(self.logdaemon.error, self.emit_error, "Failed to stop the daemon process: %s" %str(e))
-                        else:
-                                self.view(None, self.emit_message, "The daemon process has ended correctly.", silent = self.etrigan_restart)
-
-        def restart(self):
-                """ Restart the daemon. """
-                self.view(self.logdaemon.info, self.emit_message, "Restarting the daemon process...")
-                self.etrigan_restart = True
-                self.stop()
-                if self.pause_restart:
-                        time.sleep(self.pause_restart)
-                        self.etrigan_alive = True
-                self.start()
-
-        def reload(self):
-                pass
-
-        def status(self):
-                """ Get status of the daemon. """
-                self.view(self.logdaemon.info, self.emit_message, "Viewing the daemon process status...")
-
-                if self.pidfile is None:
-                        self.view(self.logdaemon.error, self.emit_error, "Cannot get the status of daemon without PIDFILE.")
-           
-                pid = self.get_pidfile()
-                if pid is None:
-                        self.view(self.logdaemon.info, self.emit_message, "The daemon process is not running.", to_exit = True)
-                else:
-                        try: 
-                                with open("/proc/%d/status" %pid, 'r') as pf:
-                                        pass
-                                self.view(self.logdaemon.info, self.emit_message, "The daemon process is running.", to_exit = True)
-                        except Exception as e:
-                                msg = "There is not a process with the PIDFILE '%s': %s" %(self.pidfile, str(e))
-                                self.view(self.logdaemon.error, self.emit_error, msg)
-
-        def flatten(self, alistoflists, ltypes = Sequence):
-                # https://stackoverflow.com/questions/2158395/flatten-an-irregular-list-of-lists/2158532#2158532
-                alistoflists = list(alistoflists)
-                while alistoflists:
-                        while alistoflists and isinstance(alistoflists[0], ltypes):
-                                alistoflists[0:1] = alistoflists[0]
-                        if alistoflists: yield alistoflists.pop(0)
-
-        def exclude(self, func):
-                from inspect import getargspec
-                args = getargspec(func)
-                if callable(func):
-                        try:
-                                args[0].pop(0)
-                        except IndexError:
-                                pass
-                        return args
-                else:
-                        self.view(self.logdaemon.error, self.emit_error, "Not a function.")
-                        return
-
-        def execute(self, some_functions):
-                returned = None
-                if isinstance(some_functions, (list, tuple)):
-                        for func in some_functions: 
-                                l_req = len(self.exclude(func)[0])
-                                
-                                if l_req == 0:
-                                        returned = func()
-                                else:
-                                        l_add = len(self.etrigan_add)
-                                        if l_req > l_add:
-                                                self.view(self.logdaemon.error, self.emit_error,
-                                                          "Can't evaluate function: given %s, required %s." %(l_add, l_req))
-                                                return
-                                        else:
-                                                arguments = self.etrigan_add[self.etrigan_index]
-                                                l_args = (len(arguments) if isinstance(arguments, list) else 1)
-                                                if (l_args > l_req) or (l_args < l_req):
-                                                        self.view(self.logdaemon.error, self.emit_error,
-                                                                  "Can't evaluate function: given %s, required %s." %(l_args, l_req))
-                                                        return
-                                                else:
-                                                        if isinstance(arguments, list):
-                                                                returned = func(*arguments)
-                                                        else:
-                                                                returned = func(arguments)
-
-                                if returned:
-                                        if isinstance(returned, (list, tuple)):
-                                                if isinstance(returned[0], int):
-                                                        self.etrigan_index = returned[0]
-                                                else:
-                                                        self.etrigan_index = slice(*map(int, returned[0].split(':')))
-                                                if returned[1:] != []:
-                                                        self.etrigan_add.append(returned[1:])
-                                                        self.etrigan_add = list(self.flatten(self.etrigan_add))
-                                        else:
-                                                self.view(self.logdaemon.error, self.emit_error, "Function should return list or tuple.")
-                                        returned = None
-                else:
-                        if some_functions is None:
-                                self.run()
-
-        def loop(self):
-                try:
-                        if self.pause_loop is None:
-                                # one-shot.
-                                self.execute(self.funcs_to_daemonize)
-                        else:
-                                if self.pause_loop >= 0:
-                                        # infinite with pause.
-                                        time.sleep(self.pause_loop)
-                                        while self.etrigan_alive:
-                                                self.execute(self.funcs_to_daemonize)
-                                                time.sleep(self.pause_loop)
-                                elif self.pause_loop == -1:
-                                        # infinite without pause.
-                                        while self.etrigan_alive:
-                                                self.execute(self.funcs_to_daemonize)
-                except Exception as e:
-                        msg = "The daemon process start method failed: %s" %str(e)
-                        self.view(self.logdaemon.error, self.emit_error, msg)
-                        
-        def quit_standard(self):
-                self.view(self.logdaemon.info, None, "Stopping the daemon process...")
-                self.delete_pidfile(self.get_pidfile())
-                self.view(self.logdaemon.info, None, "The daemon process has ended correctly.")
-
-        def quit_on_start(self):
-                """
-                Override this method when you subclass Daemon.
-                """
-                self.quit_standard()
-                
-        def quit_on_stop(self):
-                """
-                Override this method when you subclass Daemon.
-                """
-                pass
-
-        def run(self):
-                """
-                Override this method when you subclass Daemon.
-                It will be called after the process has been
-                daemonized by start() or restart().
-                """
-                pass
-                
-#-----------------------------------------------------------------------------------------------------------------------------------------------------------
-
-class JasonBlood(Etrigan):
-        def run(self):
-                jasonblood_func()
-
-def jasonblood_func():  
-        with open(os.path.join('.', 'etrigan_test.txt'), 'a') as file:
-                file.write("Yarva Demonicus Etrigan " + time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()) + '\n')
-
-def Etrigan_parser(parser = None):
-        if parser is None:
-                # create a new parser.
-                parser = argparse.ArgumentParser(description = __description__, epilog = __version__)
-        if not parser.add_help:
-                # create help argument.
-                parser.add_argument("-h", "--help", action = "help", help = "show this help message and exit")
-        
-        # attach to an existent parser.
-        parser.add_argument("operation", action = "store", choices = ["start", "stop", "restart", "status", "reload"],
-                            help = "Select an operation for daemon.", type = str)
-        parser.add_argument("--etrigan-pid",
-                            action = "store", dest = "etriganpid", default = "/tmp/etrigan.pid",
-                            help = "Choose a pidfile path. Default is \"/tmp/etrigan.pid\".", type = str) #'/var/run/etrigan.pid'
-        parser.add_argument("--etrigan-log",
-                            action = "store", dest = "etriganlog", default = os.path.join('.', "etrigan.log"),
-                            help = "Use this option to choose an output log file; for not logging don't select it. Default is \"etrigan.log\".", type = str)
-        parser.add_argument("--etrigan-lev",
-                            action = "store", dest = "etriganlev", default = "DEBUG",
-                            choices = ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"],
-                            help = "Use this option to set a log level. Default is \"DEBUG\".", type = str)
-        parser.add_argument("--etrigan-mute",
-                            action = "store_const", dest = 'etriganmute', const = True, default = False,
-                            help = "Disable all stdout and stderr messages.")
-        return parser
-
-class Etrigan_check(object):
-        def emit_opt_err(self, msg):
-                print(msg)
-                sys.exit(1)
-
-        def checkfile(self, path, typearg, typefile):
-                filename, extension = os.path.splitext(path)
-                pathname = os.path.dirname(path)
-                if not os.path.isdir(pathname):
-                        msg = "argument `%s`: invalid directory: '%s'. Exiting..." %(typearg, pathname)
-                        self.emit_opt_err(msg)
-                elif not extension == typefile:
-                        msg = "argument `%s`: not a %s file, invalid extension: '%s'. Exiting..." %(typearg, typefile, extension)
-                        self.emit_opt_err(msg)
-
-        def checkfunction(self, funcs, booleans):
-                if not isinstance(funcs, (list, tuple)):
-                        if funcs is not None:
-                                msg = "argument `funcs_to_daemonize`: provide list, tuple or None"
-                                self.emit_opt_err(msg)
-                                        
-                for elem in booleans:
-                        if not type(elem) == bool:
-                                msg = "argument `want_quit`: not a boolean."
-                                self.emit_opt_err(msg)
-        
-def Etrigan_job(type_oper, daemon_obj):
-        Etrigan_check().checkfunction(daemon_obj.funcs_to_daemonize,
-                                      [daemon_obj.want_quit])
-        if type_oper == "start":
-                daemon_obj.start()
-        elif type_oper == "stop":
-                daemon_obj.stop()
-        elif type_oper == "restart":
-                daemon_obj.restart()
-        elif type_oper == "status":
-                daemon_obj.status()
-        elif type_oper == "reload":
-                daemon_obj.reload()
-        sys.exit(0)
-
-def main():
-        # Parse arguments.
-        parser = Etrigan_parser()
-        args = vars(parser.parse_args())
-        # Check arguments.
-        Etrigan_check().checkfile(args['etriganpid'], '--etrigan-pid', '.pid')
-        Etrigan_check().checkfile(args['etriganlog'], '--etrigan-log', '.log')
-
-        # Setup daemon.
-        jasonblood_1 = Etrigan(pidfile = args['etriganpid'], logfile = args['etriganlog'], loglevel = args['etriganlev'],
-                               mute = args['etriganmute'],
-                               funcs_to_daemonize = [jasonblood_func], pause_loop = 5)
-
-##        jasonblood_2 = JasonBlood(pidfile = args['etriganpid'], logfile = args['etriganlog'], loglevel = args['etriganlev'],
-##                                  mute = args['etriganmute'],
-##                                  funcs_to_daemonize = None, pause_loop = 5)
-        # Do job.
-        Etrigan_job(args['operation'], jasonblood_1)
-        
-if __name__ == '__main__':
-        main()
diff --git a/py-kms/pykms_Server.py b/py-kms/pykms_Server.py
index 9d244de..80e549e 100755
--- a/py-kms/pykms_Server.py
+++ b/py-kms/pykms_Server.py
@@ -23,7 +23,6 @@ from pykms_Misc import check_setup, check_lcid, check_dir, check_other
 from pykms_Misc import KmsParser, KmsParserException, KmsParserHelp
 from pykms_Misc import kms_parser_get, kms_parser_check_optionals, kms_parser_check_positionals, kms_parser_check_connect
 from pykms_Format import enco, deco, pretty_printer, justify
-from Etrigan import Etrigan, Etrigan_parser, Etrigan_check, Etrigan_job
 from pykms_Connect import MultipleListener
 
 srv_version             = "py-kms_2020-10-01"
@@ -256,15 +255,6 @@ def server_options():
 
         server_parser.add_argument("-h", "--help", action = "help", help = "show this help message and exit")
 
-        ## Daemon (Etrigan) parsing.
-        daemon_parser = KmsParser(description = "daemon options inherited from Etrigan", add_help = False)
-        daemon_subparser = daemon_parser.add_subparsers(dest = "mode")
-
-        etrigan_parser = daemon_subparser.add_parser("etrigan", add_help = False)
-        etrigan_parser.add_argument("-g", "--gui", action = "store_const", dest = 'gui', const = True, default = False,
-                                    help = "Enable py-kms GUI usage.")
-        etrigan_parser = Etrigan_parser(parser = etrigan_parser)
-
         ## Connection parsing.
         connection_parser = KmsParser(description = "connect options", add_help = False)
         connection_subparser = connection_parser.add_subparsers(dest = "mode")
@@ -284,16 +274,14 @@ def server_options():
 
                 # Run help.
                 if any(arg in ["-h", "--help"] for arg in userarg):
-                        KmsParserHelp().printer(parsers = [server_parser, (daemon_parser, etrigan_parser),
-                                                           (connection_parser, connect_parser)])
+                        KmsParserHelp().printer(parsers = [server_parser, (connection_parser, connect_parser)])
 
                 # Get stored arguments.
                 pykmssrv_zeroarg, pykmssrv_onearg = kms_parser_get(server_parser)
-                etrigan_zeroarg, etrigan_onearg = kms_parser_get(etrigan_parser)
                 connect_zeroarg, connect_onearg = kms_parser_get(connect_parser)
-                subdict = {'etrigan' : (etrigan_zeroarg, etrigan_onearg, daemon_parser.parse_args),
-                           'connect' : (connect_zeroarg, connect_onearg, connection_parser.parse_args)
-                           }
+                subdict = {
+                        'connect' : (connect_zeroarg, connect_onearg, connection_parser.parse_args)
+                }
                 subpars = list(subdict.keys())
                 pykmssrv_zeroarg += subpars # add subparsers
 
@@ -309,14 +297,7 @@ def server_options():
                 if subindx:
                         # Set `daemon options` and/or `connect options` for server dict config.
                         # example cases:
-                        # 1     python3 pykms_Server.py [1.2.3.4] [1234] [--pykms_optionals] etrigan daemon_positional [--daemon_optionals] \
-                        #       connect [--connect_optionals]
-                        #
-                        # 2     python3 pykms_Server.py [1.2.3.4] [1234] [--pykms_optionals] connect [--connect_optionals] etrigan \
-                        #       daemon_positional [--daemon_optionals]
-                        #
-                        # 3     python3 pykms_Server.py [1.2.3.4] [1234] [--pykms_optionals] etrigan daemon_positional [--daemon_optionals]
-                        # 4     python3 pykms_Server.py [1.2.3.4] [1234] [--pykms_optionals] connect [--connect_optionals]
+                        # 1     python3 pykms_Server.py [1.2.3.4] [1234] [--pykms_optionals] connect [--connect_optionals]
                         first = subindx[0][0]
                         # initial.
                         kms_parser_check_optionals(userarg[0 : first], pykmssrv_zeroarg, pykmssrv_onearg, exclude_opt_len = exclude_kms)
@@ -338,7 +319,7 @@ def server_options():
                 else:
                         # Update `pykms options` for server dict config.
                         # example case:
-                        # 5     python3 pykms_Server.py [1.2.3.4] [1234] [--pykms_optionals]
+                        # 2     python3 pykms_Server.py [1.2.3.4] [1234] [--pykms_optionals]
                         kms_parser_check_optionals(userarg, pykmssrv_zeroarg, pykmssrv_onearg, exclude_opt_len = exclude_kms)
                         kms_parser_check_positionals(srv_config, server_parser.parse_args)
 
@@ -347,63 +328,6 @@ def server_options():
         except KmsParserException as e:
                 pretty_printer(put_text = "{reverse}{red}{bold}%s. Exiting...{end}" %str(e), to_exit = True)
 
-class Etrigan_Check(Etrigan_check):
-        def emit_opt_err(self, msg):
-                pretty_printer(put_text = "{reverse}{red}{bold}%s{end}" %msg, to_exit = True)
-
-class Etrigan(Etrigan):
-        def emit_message(self, message, to_exit = False):
-                if not self.mute:
-                        pretty_printer(put_text = "{reverse}{green}{bold}%s{end}" %message)
-                if to_exit:
-                        sys.exit(0)
-
-        def emit_error(self, message, to_exit = True):
-                if not self.mute:
-                        pretty_printer(put_text = "{reverse}{red}{bold}%s{end}" %message, to_exit = True)
-
-def server_daemon():
-        if 'etrigan' in srv_config.values():
-                path = os.path.join(gettempdir(), 'pykms_config.pickle')
-
-                if srv_config['operation'] in ['stop', 'restart', 'status'] and len(sys.argv[1:]) > 2:
-                        pretty_printer(put_text = "{reverse}{red}{bold}too much arguments with etrigan '%s'. Exiting...{end}" %srv_config['operation'],
-                                       to_exit = True)
-
-                # Check file arguments.
-                Etrigan_Check().checkfile(srv_config['etriganpid'], '--etrigan-pid', '.pid')
-                Etrigan_Check().checkfile(srv_config['etriganlog'], '--etrigan-log', '.log')
-
-                if srv_config['gui']:
-                        pass
-                else:
-                        if srv_config['operation'] == 'start':
-                                with open(path, 'wb') as file:
-                                        pickle.dump(srv_config, file, protocol = pickle.HIGHEST_PROTOCOL)
-                        elif srv_config['operation'] in ['stop', 'status', 'restart']:
-                                with open(path, 'rb') as file:
-                                        old_srv_config = pickle.load(file)
-                                old_srv_config = {x: old_srv_config[x] for x in old_srv_config if x not in ['operation']}
-                                srv_config.update(old_srv_config)
-
-                serverdaemon = Etrigan(srv_config['etriganpid'],
-                                       logfile = srv_config['etriganlog'], loglevel = srv_config['etriganlev'],
-                                       mute = srv_config['etriganmute'], pause_loop = None)
-
-                if srv_config['operation'] in ['start', 'restart']:
-                        serverdaemon.want_quit = True
-                        if srv_config['gui']:
-                                serverdaemon.funcs_to_daemonize = [server_with_gui]
-                        else:
-                                server_without_gui = ServerWithoutGui()
-                                serverdaemon.funcs_to_daemonize = [server_without_gui.start, server_without_gui.join]
-                                indx_for_clean = lambda: (0, )
-                                serverdaemon.quit_on_stop = [indx_for_clean, server_without_gui.clean]
-                elif srv_config['operation'] == 'stop':
-                        os.remove(path)
-
-                Etrigan_job(srv_config['operation'], serverdaemon)
-
 def server_check():
         # Setup and some checks.
         check_setup(srv_config, srv_options, loggersrv, where = "srv")
@@ -543,35 +467,15 @@ def server_main_terminal():
         server_check()
         serverthread.checked = True
 
-        if 'etrigan' not in srv_config.values():
-                # (without GUI) and (without daemon).
-                # Run threaded server.
-                serverqueue.put('start')
-                # Wait to finish.
-                try:
-                        while serverthread.is_alive():
-                                serverthread.join(timeout = 0.5)
-                except (KeyboardInterrupt, SystemExit):
-                        server_terminate(serverthread, exit_server = True, exit_thread = True)
-        else:
-                # (with or without GUI) and (with daemon)
-                # Setup daemon (eventually).
-                pretty_printer(log_obj = loggersrv.warning, put_text = "{reverse}{yellow}{bold}Etrigan support is deprecated and will be removed in the future!{end}")
-                server_daemon()
-
-def server_with_gui():
-        import pykms_GuiBase
-
-        pretty_printer(log_obj = loggersrv.warning, put_text = "{reverse}{yellow}{bold}Etrigan GUI support is deprecated and will be removed in the future!{end}")
-
-        root = pykms_GuiBase.KmsGui()
-        root.title(pykms_GuiBase.gui_description + ' (' + pykms_GuiBase.gui_version + ')')
-        root.mainloop()
-
-def server_main_no_terminal():
-        # Run tkinter GUI.
-        # (with GUI) and (without daemon).
-        server_with_gui()
+        # (without GUI) and (without daemon).
+        # Run threaded server.
+        serverqueue.put('start')
+        # Wait to finish.
+        try:
+                while serverthread.is_alive():
+                        serverthread.join(timeout = 0.5)
+        except (KeyboardInterrupt, SystemExit):
+                server_terminate(serverthread, exit_server = True, exit_thread = True)
 
 class kmsServerHandler(socketserver.BaseRequestHandler):
         def setup(self):
@@ -636,10 +540,4 @@ serverthread.daemon = True
 serverthread.start()
 
 if __name__ == "__main__":
-        if sys.stdout.isatty():
-                server_main_terminal()
-        else:
-                try:
-                        server_main_no_terminal()
-                except:
-                        server_main_terminal()
+        server_main_terminal()