# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

# Don't use the unicode-wrapped os and shutil modules here since
# the whole _selinux module itself will be wrapped.
import os
import shutil

import portage
from portage import _encodings
from portage import _native_string, _unicode_decode
from portage.localization import _
portage.proxy.lazyimport.lazyimport(globals(),
	'selinux')

def copyfile(src, dest):
	src = _native_string(src, encoding=_encodings['fs'], errors='strict')
	dest = _native_string(dest, encoding=_encodings['fs'], errors='strict')
	(rc, ctx) = selinux.lgetfilecon(src)
	if rc < 0:
		if sys.hexversion < 0x3000000:
			src = _unicode_decode(src, encoding=_encodings['fs'], errors='replace')
		raise OSError(_("copyfile: Failed getting context of \"%s\".") % src)

	setfscreate(ctx)
	try:
		shutil.copyfile(src, dest)
	finally:
		setfscreate()

def getcontext():
	(rc, ctx) = selinux.getcon()
	if rc < 0:
		raise OSError(_("getcontext: Failed getting current process context."))

	return ctx

def is_selinux_enabled():
	return selinux.is_selinux_enabled()

def mkdir(target, refdir):
	target = _native_string(target, encoding=_encodings['fs'], errors='strict')
	refdir = _native_string(refdir, encoding=_encodings['fs'], errors='strict')
	(rc, ctx) = selinux.getfilecon(refdir)
	if rc < 0:
		if sys.hexversion < 0x3000000:
			refdir = _unicode_decode(refdir, encoding=_encodings['fs'], errors='replace')
		raise OSError(
			_("mkdir: Failed getting context of reference directory \"%s\".") \
			% refdir)

	setfscreate(ctx)
	try:
		os.mkdir(target)
	finally:
		setfscreate()

def rename(src, dest):
	src = _native_string(src, encoding=_encodings['fs'], errors='strict')
	dest = _native_string(dest, encoding=_encodings['fs'], errors='strict')
	(rc, ctx) = selinux.lgetfilecon(src)
	if rc < 0:
		if sys.hexversion < 0x3000000:
			src = _unicode_decode(src, encoding=_encodings['fs'], errors='replace')
		raise OSError(_("rename: Failed getting context of \"%s\".") % src)

	setfscreate(ctx)
	try:
		os.rename(src, dest)
	finally:
		setfscreate()

def settype(newtype):
	ret = getcontext().split(":")
	ret[2] = newtype
	return ":".join(ret)

def setexec(ctx="\n"):
	ctx = _native_string(ctx, encoding=_encodings['content'], errors='strict')
	if selinux.setexeccon(ctx) < 0:
		if sys.hexversion < 0x3000000:
			ctx = _unicode_decode(ctx, encoding=_encodings['content'], errors='replace')
		if selinux.security_getenforce() == 1:
			raise OSError(_("Failed setting exec() context \"%s\".") % ctx)
		else:
			portage.writemsg("!!! " + \
				_("Failed setting exec() context \"%s\".") % ctx, \
				noiselevel=-1)

def setfscreate(ctx="\n"):
	ctx = _native_string(ctx, encoding=_encodings['content'], errors='strict')
	if selinux.setfscreatecon(ctx) < 0:
		if sys.hexversion < 0x3000000:
			ctx = _unicode_decode(ctx, encoding=_encodings['content'], errors='replace')
		raise OSError(
			_("setfscreate: Failed setting fs create context \"%s\".") % ctx)

class spawn_wrapper(object):
	"""
	Create a wrapper function for the given spawn function. When the wrapper
	is called, it will adjust the arguments such that setexec() to be called
	*after* the fork (thereby avoiding any interference with concurrent
	threads in the calling process).
	"""
	__slots__ = ("_con", "_spawn_func")

	def __init__(self, spawn_func, selinux_type):
		self._spawn_func = spawn_func
		selinux_type = _native_string(selinux_type, encoding=_encodings['content'], errors='strict')
		self._con = settype(selinux_type)

	def __call__(self, *args, **kwargs):

		pre_exec = kwargs.get("pre_exec")

		def _pre_exec():
			if pre_exec is not None:
				pre_exec()
			setexec(self._con)

		kwargs["pre_exec"] = _pre_exec
		return self._spawn_func(*args, **kwargs)

def symlink(target, link, reflnk):
	target = _native_string(target, encoding=_encodings['fs'], errors='strict')
	link = _native_string(link, encoding=_encodings['fs'], errors='strict')
	reflnk = _native_string(reflnk, encoding=_encodings['fs'], errors='strict')
	(rc, ctx) = selinux.lgetfilecon(reflnk)
	if rc < 0:
		if sys.hexversion < 0x3000000:
			reflnk = _unicode_decode(reflnk, encoding=_encodings['fs'], errors='replace')
		raise OSError(
			_("symlink: Failed getting context of reference symlink \"%s\".") \
			% reflnk)

	setfscreate(ctx)
	try:
		os.symlink(target, link)
	finally:
		setfscreate()
