#!/usr/bin/python -b
# Copyright 1999-2021 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

#
# dispatch-conf -- Integrate modified configs, post-emerge
#
#  Jeremy Wohl (http://igmus.org)
#
# TODO
#  dialog menus
#

import atexit
import io
import re
import subprocess
import sys
import termios
import tty

from stat import ST_GID, ST_MODE, ST_UID
from random import random

try:
	import curses
except ImportError:
	curses = None

from os import path as osp
if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
	sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "lib"))
import portage
portage._internal_caller = True
from portage import os, shutil
from portage import _encodings, _unicode_decode
from portage.dispatch_conf import (diffstatusoutput, diff_mixed_wrapper,
	perform_conf_update_hooks, perform_conf_update_session_hooks)
from portage.process import find_binary, spawn
from portage.util import writemsg, writemsg_stdout

FIND_EXTANT_CONFIGS  = "find '%s' %s -name '._cfg????_%s' ! -name '.*~' ! -iname '.*.bak' -print"
DIFF_CONTENTS        = "diff -Nu '%s' '%s'"

if "case-insensitive-fs" in portage.settings.features:
    FIND_EXTANT_CONFIGS = FIND_EXTANT_CONFIGS.replace(
        "-name '._cfg", "-iname '._cfg")

# We need a secure scratch dir and python does silly verbose errors on the use of tempnam
oldmask = os.umask(0o077)
SCRATCH_DIR = None
while SCRATCH_DIR is None:
    try:
        mydir = "/tmp/dispatch-conf."
        for x in range(0,8):
            if int(random() * 3) == 0:
                mydir += chr(int(65+random()*26.0))
            elif int(random() * 2) == 0:
                mydir += chr(int(97+random()*26.0))
            else:
                mydir += chr(int(48+random()*10.0))
        if os.path.exists(mydir):
            continue
        os.mkdir(mydir)
        SCRATCH_DIR = mydir
    except OSError as e:
        if e.errno != 17:
            raise
os.umask(oldmask)

# Ensure the scratch dir is deleted
def cleanup(mydir=SCRATCH_DIR):
    shutil.rmtree(mydir)
atexit.register(cleanup)

MANDATORY_OPTS = [ 'archive-dir', 'diff', 'replace-cvs', 'replace-wscomments', 'merge' ]

def cmd_var_is_valid(cmd):
    """
    Return true if the first whitespace-separated token contained
    in cmd is an executable file, false otherwise.
    """
    cmd = portage.util.shlex_split(cmd)
    if not cmd:
        return False

    if os.path.isabs(cmd[0]):
        return os.access(cmd[0], os.EX_OK)

    return find_binary(cmd[0]) is not None

diff = diff_mixed_wrapper(diffstatusoutput, DIFF_CONTENTS)

class dispatch:
    options = {}

    def grind (self, config_paths):
        confs = []
        count = 0

        perform_conf_update_session_hooks("pre-session")

        config_root = portage.settings["EPREFIX"] or os.sep
        self.options = portage.dispatch_conf.read_config(MANDATORY_OPTS)

        if "log-file" in self.options:
            if os.path.isfile(self.options["log-file"]):
                shutil.copy(self.options["log-file"], self.options["log-file"] + '.old')
            if os.path.isfile(self.options["log-file"]) \
               or not os.path.exists(self.options["log-file"]):
                open(self.options["log-file"], 'w').close() # Truncate it
                os.chmod(self.options["log-file"], 0o600)

        pager = self.options.get("pager")
        if pager is None or not cmd_var_is_valid(pager):
            pager = os.environ.get("PAGER")
            if pager is None or not cmd_var_is_valid(pager):
                pager = "cat"

        pager_basename = os.path.basename(portage.util.shlex_split(pager)[0])
        if pager_basename == "less":
            less_opts = self.options.get("less-opts")
            if less_opts is not None and less_opts.strip():
                pager += " " + less_opts

        if pager_basename == "cat":
            pager = ""
        else:
            pager = " | " + pager

        #
        # Build list of extant configs
        #

        for path in config_paths:
            path = portage.normalize_path(
                 os.path.join(config_root, path.lstrip(os.sep)))

            # Protect files that don't exist (bug #523684). If the
            # parent directory doesn't exist, we can safely skip it.
            if not os.path.isdir(os.path.dirname(path)):
                continue

            basename = "*"
            find_opts = "-name '.*' -type d -prune -o"
            if not os.path.isdir(path):
                path, basename = os.path.split(path)
                find_opts = "-maxdepth 1"

            try:
                path_list = _unicode_decode(subprocess.check_output(
                    portage.util.shlex_split(FIND_EXTANT_CONFIGS %
                    (path, find_opts, basename))),
                    errors='strict').splitlines()
            except subprocess.CalledProcessError:
                pass
            else:
                confs.extend(self.massage(path_list))

        if self.options['use-rcs'] == 'yes':
            for rcs_util in ("rcs", "ci", "co", "rcsmerge"):
                if not find_binary(rcs_util):
                    print('dispatch-conf: Error finding all RCS utils and " + \
                        "use-rcs=yes in config; fatal', file=sys.stderr)
                    return False


        # config file freezing support
        frozen_files = set(self.options.get("frozen-files", "").split())
        auto_zapped = []
        protect_obj = portage.util.ConfigProtect(
            config_root, config_paths,
            portage.util.shlex_split(
            portage.settings.get('CONFIG_PROTECT_MASK', '')),
            case_insensitive=("case-insensitive-fs"
            in portage.settings.features))

        #
        # Remove new configs identical to current
        #                  and
        # Auto-replace configs a) whose differences are simply CVS interpolations,
        #                  or  b) whose differences are simply ws or comments,
        #                  or  c) in paths now unprotected by CONFIG_PROTECT_MASK,
        #

        def f (conf):
            mrgconf = re.sub(r'\._cfg', '._mrg', conf['new'])
            archive = os.path.join(self.options['archive-dir'], conf['current'].lstrip('/'))
            if self.options['use-rcs'] == 'yes':
                mrgfail = portage.dispatch_conf.rcs_archive(archive, conf['current'], conf['new'], mrgconf)
            else:
                mrgfail = portage.dispatch_conf.file_archive(archive, conf['current'], conf['new'], mrgconf)
            if os.path.lexists(archive + '.dist'):
                unmodified = len(diff(conf['current'], archive + '.dist')[1]) == 0
            else:
                unmodified = 0
            if os.path.exists(mrgconf):
                if mrgfail or len(diff(conf['new'], mrgconf)[1]) == 0:
                    os.unlink(mrgconf)
                    newconf = conf['new']
                else:
                    newconf = mrgconf
            else:
                newconf = conf['new']

            if newconf == mrgconf and \
                self.options.get('ignore-previously-merged') != 'yes' and \
                os.path.lexists(archive+'.dist') and \
                len(diff(archive+'.dist', conf['new'])[1]) == 0:
                # The current update is identical to the archived .dist
                # version that has previously been merged.
                os.unlink(mrgconf)
                newconf = conf['new']

            mystatus, myoutput = diff(conf['current'], newconf)
            myoutput_len = len(myoutput)
            same_file = 0 == myoutput_len
            if mystatus >> 8 == 2:
                # Binary files differ
                same_cvs = False
                same_wsc = False
            else:
                # Extract all the normal diff lines (ignore the headers).
                mylines = re.findall('^[+-][^\n+-].*$', myoutput, re.MULTILINE)

                # Filter out all the cvs headers
                cvs_header = re.compile('# [$]Header:')
                cvs_lines = list(filter(cvs_header.search, mylines))
                same_cvs = len(mylines) == len(cvs_lines)

                # Filter out comments and whitespace-only changes.
                # Note: be nice to also ignore lines that only differ in whitespace...
                wsc_lines = []
                for x in [r'^[-+]\s*#', r'^[-+]\s*$']:
                   wsc_lines += list(filter(re.compile(x).match, mylines))
                same_wsc = len(mylines) == len(wsc_lines)

            # Do options permit?
            same_cvs = same_cvs and self.options['replace-cvs'] == 'yes'
            same_wsc = same_wsc and self.options['replace-wscomments'] == 'yes'
            unmodified = unmodified and self.options['replace-unmodified'] == 'yes'

            if same_file:
                os.unlink (conf ['new'])
                self.post_process(conf['current'])
                if os.path.exists(mrgconf):
                    os.unlink(mrgconf)
                return False
            elif conf['current'] in frozen_files:
                """Frozen files are automatically zapped. The new config has
                already been archived with a .new suffix.  When zapped, it is
                left with the .new suffix (post_process is skipped), since it
                hasn't been merged into the current config."""
                auto_zapped.append(conf['current'])
                os.unlink(conf['new'])
                try:
                    os.unlink(mrgconf)
                except OSError:
                    pass
                return False
            elif unmodified or same_cvs or same_wsc or \
                not protect_obj.isprotected(conf['current']):
                self.replace(newconf, conf['current'])
                self.post_process(conf['current'])
                if newconf == mrgconf:
                    os.unlink(conf['new'])
                elif os.path.exists(mrgconf):
                    os.unlink(mrgconf)
                return False
            else:
                return True

        confs = [x for x in confs if f(x)]

        #
        # Interactively process remaining
        #

        valid_input = "qhtnmlezu"

        def diff_pager(file1, file2):
            cmd = self.options['diff'] % (file1, file2)
            cmd += pager
            spawn_shell(cmd)

        diff_pager = diff_mixed_wrapper(diff_pager)

        for conf in confs:
            count = count + 1

            newconf = conf['new']
            mrgconf = re.sub(r'\._cfg', '._mrg', newconf)
            if os.path.exists(mrgconf):
                newconf = mrgconf
            show_new_diff = 0

            while 1:
                clear_screen()
                if show_new_diff:
                    diff_pager(conf['new'], mrgconf)
                    show_new_diff = 0
                else:
                    diff_pager(conf['current'], newconf)

                print()
                writemsg_stdout('>> (%i of %i) -- %s\n' % (count, len(confs), conf['current']), noiselevel=-1)
                print('>> q quit, h help, n next, e edit-new, z zap-new, u use-new\n   m merge, t toggle-merge, l look-merge: ', end=' ')

                # In some cases getch() will return some spurious characters
                # that do not represent valid input. If we don't validate the
                # input then the spurious characters can cause us to jump
                # back into the above "diff" command immediatly after the user
                # has exited it (which can be quite confusing and gives an
                # "out of control" feeling).
                while True:
                    c = getch()
                    if c in valid_input:
                        sys.stdout.write('\n')
                        sys.stdout.flush()
                        break

                if c == 'q':
                    perform_conf_update_session_hooks("post-session")
                    sys.exit (0)
                if c == 'h':
                    self.do_help ()
                    continue
                elif c == 't':
                    if newconf == mrgconf:
                        newconf = conf['new']
                    elif os.path.exists(mrgconf):
                        newconf = mrgconf
                    continue
                elif c == 'n':
                    break
                elif c == 'm':
                    merged = SCRATCH_DIR+"/"+os.path.basename(conf['current'])
                    print()
                    ret = os.system (self.options['merge'] % (merged, conf ['current'], newconf))
                    ret = os.WEXITSTATUS(ret)
                    if ret < 2:
                        ret = 0
                    if ret:
                        print("Failure running 'merge' command")
                        continue
                    shutil.copyfile(merged, mrgconf)
                    os.remove(merged)
                    mystat = os.lstat(conf['new'])
                    os.chmod(mrgconf, mystat[ST_MODE])
                    os.chown(mrgconf, mystat[ST_UID], mystat[ST_GID])
                    newconf = mrgconf
                    continue
                elif c == 'l':
                    show_new_diff = 1
                    continue
                elif c == 'e':
                    if 'EDITOR' not in os.environ:
                        os.environ['EDITOR']='nano'
                    os.system(os.environ['EDITOR'] + ' ' + newconf)
                    continue
                elif c == 'z':
                    os.unlink(conf['new'])
                    if os.path.exists(mrgconf):
                        os.unlink(mrgconf)
                    break
                elif c == 'u':
                    self.replace(newconf, conf ['current'])
                    self.post_process(conf['current'])
                    if newconf == mrgconf:
                        os.unlink(conf['new'])
                    elif os.path.exists(mrgconf):
                        os.unlink(mrgconf)
                    break
                else:
                    raise AssertionError("Invalid Input: %s" % c)

        if auto_zapped:
            print()
            print(" One or more updates are frozen and have been automatically zapped:")
            print()
            for frozen in auto_zapped:
                writemsg_stdout("  * '%s'\n" % frozen, noiselevel=-1)
            print()

        perform_conf_update_session_hooks("post-session")

    def replace (self, newconf, curconf):
        """Replace current config with the new/merged version.  Also logs
        the diff of what changed into the configured log file."""
        if "log-file" in self.options:
            status, output = diff(curconf, newconf)
            with io.open(self.options["log-file"], mode="a",
                encoding=_encodings["stdio"]) as f:
                f.write(output + "\n")

        perform_conf_update_hooks("pre-update", curconf)

        try:
            os.rename(newconf, curconf)
        except (IOError, os.error) as why:
            writemsg('dispatch-conf: Error renaming %s to %s: %s; fatal\n' % \
                  (newconf, curconf, str(why)), noiselevel=-1)
            return

        perform_conf_update_hooks("post-update", curconf)


    def post_process(self, curconf):
        archive = os.path.join(self.options['archive-dir'], curconf.lstrip('/'))
        if self.options['use-rcs'] == 'yes':
            portage.dispatch_conf.rcs_archive_post_process(archive)
        else:
            portage.dispatch_conf.file_archive_post_process(archive)


    def massage (self, newconfigs):
        """Sort, rstrip, remove old versions, break into triad hash.

        Triad is dictionary of current (/etc/make.conf), new (/etc/._cfg0003_make.conf)
        and dir (/etc).

        We keep ._cfg0002_conf over ._cfg0001_conf and ._cfg0000_conf.
        """
        h = {}
        configs = []
        newconfigs.sort ()

        for nconf in newconfigs:
            # Use strict mode here, because we want to know if it fails,
            # and portage only merges files with valid UTF-8 encoding.
            nconf = _unicode_decode(nconf, errors='strict').rstrip()
            conf  = re.sub (r'\._cfg\d+_', '', nconf)
            dirname   = os.path.dirname(nconf)
            conf_map  = {
                'current' : conf,
                'dir'     : dirname,
                'new'     : nconf,
            }

            if conf in h:
                mrgconf = re.sub(r'\._cfg', '._mrg', h[conf]['new'])
                if os.path.exists(mrgconf):
                    os.unlink(mrgconf)
                os.unlink(h[conf]['new'])
                h[conf].update(conf_map)
            else:
                h[conf] = conf_map
                configs.append(conf_map)

        return configs


    def do_help (self):
        print()
        print()

        print('  u -- update current config with new config and continue')
        print('  z -- zap (delete) new config and continue')
        print('  n -- skip to next config, leave all intact')
        print('  e -- edit new config')
        print('  m -- interactively merge current and new configs')
        print('  l -- look at diff between pre-merged and merged configs')
        print('  t -- toggle new config between merged and pre-merged state')
        print('  h -- this screen')
        print('  q -- quit')

        print(); print('press any key to return to diff...', end=' ')

        getch ()


def getch ():
    # from ASPN - Danny Yoo
    #

    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    try:
        tty.setraw(sys.stdin.fileno())
        ch = sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    return ch

def clear_screen():
    if curses is not None:
        try:
            curses.setupterm()
            sys.stdout.write(_unicode_decode(curses.tigetstr("clear")))
            sys.stdout.flush()
            return
        except curses.error:
            pass
    os.system("clear 2>/dev/null")

shell = os.environ.get("SHELL")
if not shell or not os.access(shell, os.EX_OK):
    shell = find_binary("sh")

def spawn_shell(cmd):
    if shell:
        sys.__stdout__.flush()
        sys.__stderr__.flush()
        spawn([shell, "-c", cmd], env=os.environ,
            fd_pipes = {  0 : portage._get_stdin().fileno(),
                          1 : sys.__stdout__.fileno(),
                          2 : sys.__stderr__.fileno()})
    else:
        os.system(cmd)

def usage(argv):
    print('dispatch-conf: sane configuration file update\n')
    print('Usage: dispatch-conf [config dirs]\n')
    print('See the dispatch-conf(1) man page for more details')
    sys.exit(os.EX_OK)

for x in sys.argv:
    if x in ('-h', '--help'):
        usage(sys.argv)
    elif x in ('--version',):
        print("Portage", portage.VERSION)
        sys.exit(os.EX_OK)

# run
d = dispatch ()

if len(sys.argv) > 1:
    # for testing
    d.grind(sys.argv[1:])
else:
    d.grind(portage.util.shlex_split(
        portage.settings.get('CONFIG_PROTECT', '')))
