#!/bin/sh

# Copyright (C)2007 Sun Microsystems, Inc.
# Copyright (C)2009-2014, 2016, 2018-2020 D. R. Commander
#
# This library is free software and may be redistributed and/or modified under
# the terms of the wxWindows Library License, Version 3.1 or (at your option)
# any later version.  The full license is in the LICENSE.txt file included
# with this distribution.
#
# This library 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
# wxWindows Library License for more details.

VGLUSERSONLY=1
DISABLEXTEST=1
FBDEVVGLUSERSONLY=1
RMMODNEEDED=0
UNATTENDED=0
SELINUX=0
WAYLAND=0

GID=
GROUPADD=/usr/sbin/groupadd
if [ ! -x $GROUPADD ]; then GROUPADD=groupadd; fi
if [ "`uname -s`" = "FreeBSD" ]; then
	GROUPADD="pw groupadd"
fi
LSMOD=/sbin/lsmod
if [ ! -x $LSMOD ]; then LSMOD=lsmod; fi
RMMOD=/sbin/rmmod
if [ ! -x $RMMOD ]; then RMMOD=rmmod; fi
SEMANAGE=
RESTORECON=

VGLGENKEY=vglgenkey

usage()
{
	echo
	echo "USAGE: $0 [flags]"
	echo
	echo "Flags (for unattended mode):"
	echo "-config         Configure server for use with VirtualGL"
	echo "-unconfig       Unconfigure server for use with VirtualGL"
	echo "-s              Restrict 3D X server access to vglusers group [default]"
	echo "+s              Open 3D X server access to all users of this machine"
	echo "-f              Restrict framebuffer device access to vglusers group [default]"
	echo "+f              Open framebuffer device access to all users of this machine"
	echo "-t              Disable XTEST extension [default]"
	echo "+t              Enable XTEST extension"
	echo
	echo "Flags (for both interactive and unattended modes):"
	echo "-gid <g>  If vglusers group must be created, then set its group ID to <g>"
	echo
	exit $1
}

uid()
{
	id | cut -f2 -d = | cut -f1 -d \(;
}

maketemp()
{
	umask 077
	mktemp /tmp/$1.XXXXXX || exit 1
}

removeline()
{
	if [ -z "$1" -o -z "$2" ]; then
		echo 'USAGE: removeline <filename> <pattern>'
		return
	fi
	TMPFILE=`maketemp vglserver_config_1`
	sed "/$2/d" $1 >$TMPFILE && cp $TMPFILE $1
	if [ -f $TMPFILE ]; then rm $TMPFILE; fi
}

replaceline()
{
	if [ -z "$1" -o -z "$2" -o -z "$3" ]; then
		echo 'USAGE: replaceline <filename> <pattern to replace> <new text>'
		return
	fi
	TMPFILE=`maketemp vglserver_config_2`
	sed "s/^.*$2.*$/$3/g" $1 >$TMPFILE && cp $TMPFILE $1
	if [ -f $TMPFILE ]; then rm $TMPFILE; fi
}

uncommentline()
{
	if [ -z "$1" -o -z "$2" ]; then
		echo 'USAGE: uncommentline <filename> <regex of line to uncomment>'
		return
	fi
	TMPFILE=`maketemp vglserver_config_3`
	sed "/$2/s/^[ \t]*#*//g" $1 >$TMPFILE && cp $TMPFILE $1
	if [ -f $TMPFILE ]; then rm $TMPFILE; fi
}

commentline()
{
	uncommentline $1 $2
	if [ -z "$1" -o -z "$2" ]; then
		echo 'USAGE: commentline <filename> <regex of line to comment>'
		return
	fi
	TMPFILE=`maketemp vglserver_config_4`
	sed "/$2/s/^/#/g" $1 >$TMPFILE && cp $TMPFILE $1
	if [ -f $TMPFILE ]; then rm $TMPFILE; fi
}

addtobottom()
{
	if [ -z "$1" -o -z "$2" ]; then
		echo 'USAGE: addtobottom <filename> <line to add>'
		return
	fi
	TMPFILE=`maketemp vglserver_config_10`
	cat $1 >$TMPFILE && echo $2 >>$TMPFILE && cp $TMPFILE $1
	if [ -f $TMPFILE ]; then rm $TMPFILE; fi
}

addtotop()
{
	if [ -z "$1" -o -z "$2" ]; then
		echo 'USAGE: addtotop <filename> <line to add>'
		return
	fi
	TMPFILE=`maketemp vglserver_config_5`
	SCRFILE=`maketemp vglserver_config_6`
	AWK=nawk
	type $AWK >/dev/null 2>/dev/null || AWK=gawk
	cat > $SCRFILE <<EOF
BEGIN {DONE=0} {
	if(/^$|^[^#]/ && DONE==0) {
		printf("$2"); printf("\n");
		DONE=1;
	}
	print \$0
}
END {
	if(DONE==0) {
		printf("$2"); printf("\n");
	}
}
EOF
	$AWK -f $SCRFILE $1 >$TMPFILE && cp $TMPFILE $1
	if [ -f $SCRFILE ]; then rm $SCRFILE; fi
	if [ -f $TMPFILE ]; then rm $TMPFILE; fi
}

addtoconf()
{
	if [ -z "$1" -o -z "$2" -o -z "$3" -o -z "$4" ]; then
		echo 'USAGE: addtoconf <filename> <stanza name> <search string> <line to add>'
		return
	fi
	grep "\[$3\]" $1 >/dev/null 2>/dev/null
	if [ $? = 0 ]; then
		TMPFILE=`maketemp vglserver_config_7`
		AWK=nawk
		type $AWK >/dev/null 2>/dev/null || AWK=gawk
		$AWK -vstanza=$2 -vadd="$4" '{ if($0 ~ stanza) { print "["stanza"]"; print add } else print $0; }' $1 >$TMPFILE && cp $TMPFILE $1
		if [ -f $TMPFILE ]; then rm $TMPFILE; fi
	else
		addtobottom $1 "[$2]"
		addtobottom $1 "$4"
	fi
}

backup()
{
	if [ -z "$1" ]; then
		echo 'USAGE: backup <filename>'
		return
	fi
	if [ ! -f $1.orig.vgl ]; then
		cp $1 $1.orig.vgl
		echo ... $1 has been saved as $1.orig.vgl ...
	fi
}

delvglgenkey()
{
	echo ... Removing X server access from $1 script ...
	removeline $1 vglgenkey
	removeline $1 "xhost +*"
}

addvglgenkey()
{
	backup $1
	if [ "$VGLUSERSONLY" = "1" ]; then
		echo ... Adding vglgenkey to $1 script ...
	else
		echo ... Adding xhost \+LOCAL\: to $1 script ...
	fi
	removeline $1 vglgenkey
	removeline $1 "xhost +*"
	if [ "$VGLUSERSONLY" = "1" ]; then
		if [ "$2" = "bottom" ]; then
			addtobottom $1 $VGLGENKEY
		else
			addtotop $1 $VGLGENKEY
		fi
	else
		if [ "$2" = "bottom" ]; then
			addtobottom $1 "xhost +LOCAL:"
		else
			addtotop $1 "xhost +LOCAL:"
		fi
	fi
}

addvglgenkey_lightdm()
{
	backup $1
	if [ "$VGLUSERSONLY" = "1" ]; then
		echo ... Adding greeter-setup-script=vglgenkey to $1 ...
	else
		echo ... Adding greeter-setup-script=xhost \+LOCAL\: to $1 ...
	fi
	removeline $1 display-setup-script
	removeline $1 greeter-setup-script
	if [ "$VGLUSERSONLY" = "1" ]; then
		addtoconf $1 "Seat:seat*" "Seat:seat\*" greeter-setup-script=$VGLGENKEY
	else
		addtoconf $1 "Seat:seat*" "Seat:seat\*" "greeter-setup-script=xhost +LOCAL:"
	fi
}

disablextest()
{
	if [ -z "$1" ]; then
		echo 'USAGE: disablextest <filename>'
		return
	fi
	backup $1
	echo ... Disabling XTEST extension in $1 ...
	TMPFILE=`maketemp vglserver_config_7`
	sed -e "/\/X11\/X\>/s/[ #\t]*-tst//g" -e "/\/bin\/X\>/s/[ #\t]*-tst//g" -e "/\/bin\/Xorg\>/s/[ #\t]*-tst//g" -e "/\/bin\/Xsun\>/s/[ #\t]*-tst//g" -e "/\/bin\/Xserver\>/s/[ #\t]*-tst//g" $1 >$TMPFILE && cp $TMPFILE $1 && (
		sed -e "/\/X11\/X\>/s/$/\ -tst/g" -e "/\/bin\/X\>/s/$/\ -tst/g" -e "/\/bin\/Xorg\>/s/$/\ -tst/g" -e "/\/bin\/Xsun\>/s/$/\ -tst/g" -e "/\/bin\/Xserver\>/s/$/\ -tst/g" $1 >$TMPFILE && cp $TMPFILE $1
	)
	if [ -f $TMPFILE ]; then rm $TMPFILE; fi
}

disablextestkdm()
{
	if [ -z "$1" ]; then
		echo 'USAGE: disablextestkdm <filename>'
		return
	fi
	backup $1
	echo ... Disabling XTEST extension in $1 ...
	TMPFILE=`maketemp vglserver_config_12`
	uncommentline $1 ServerArgsLocal
	sed -e "/ServerArgsLocal\>/s/[ #\t]*-tst//g" $1 >$TMPFILE && cp $TMPFILE $1 && (
		sed -e "/ServerArgsLocal\>/s/$/\ -tst/g" $1 >$TMPFILE && cp $TMPFILE $1
	)
	if [ -f $TMPFILE ]; then rm $TMPFILE; fi
}

enablextest()
{
	if [ -z "$1" ]; then
		echo 'USAGE: enablextest <filename>'
		return
	fi
	echo ... Enabling XTEST extension in $1 ...
	TMPFILE=`maketemp vglserver_config_8`
	sed -e "/\/X11\/X\>/s/[ #\t]*-tst//g" -e "/\/bin\/X\>/s/[ #\t]*-tst//g" -e "/\/bin\/Xorg\>/s/[ #\t]*-tst//g" -e "/\/bin\/Xsun\>/s/[ #\t]*-tst//g" -e "/\/bin\/Xserver\>/s/[ #\t]*-tst//g" $1 >$TMPFILE && cp $TMPFILE $1
	if [ -f $TMPFILE ]; then rm $TMPFILE; fi
}

enablextestkdm()
{
	if [ -z "$1" ]; then
		echo 'USAGE: enablextestkdm <filename>'
		return
	fi
	echo ... Enabling XTEST extension in $1 ...
	TMPFILE=`maketemp vglserver_config_11`
	sed -e "/ServerArgsLocal\>/s/[ #\t]*-tst//g" $1 >$TMPFILE && cp $TMPFILE $1
	if [ -f $TMPFILE ]; then rm $TMPFILE; fi
}

disallowgdmtcp()
{
	echo ... Commenting out DisallowTCP line \(if it exists\) in $1 ...
	commentline $1 "DisallowTCP.*=.*"
}

disablewaylandgdm()
{
	backup $1
	echo ... Disabling Wayland in $1 ...
	grep -q "WaylandEnable.*=.*false" $1 && (
		uncommentline $1 "WaylandEnable.*=.*false"
	) || (
		grep -q "WaylandEnable" $1 && (
			replaceline $1 WaylandEnable "WaylandEnable=false"
		) || (
			removeline $1 WaylandEnable
			addtoconf $1 "daemon" "daemon" WaylandEnable=false
		)
	)
}

setdripermissions()
{
	if [ -z "$1" ]; then
		echo 'USAGE: setdripermissions <filename> [backup]'
		return
	fi
	if [ ! -f $1 ]; then return; fi
	if [ "$2" = "backup" ]; then
		backup $1
	fi
	if [ "$FBDEVVGLUSERSONLY" = "1" ]; then
		echo "... Modifying $1 to enable DRI permissions"
		echo "    for vglusers group ..."
	else
		echo "... Modifying $1 to enable DRI permissions"
		echo "    for all users ..."
	fi
	TMPFILE=`maketemp vglserver_config_9`
	# Delete Section "DRI" stanza
	sed '/Section.*"DRI"/,/EndSection/d' $1 >$TMPFILE && cp $TMPFILE $1
	# Ensure that exactly one line separates each stanza
	sed -n '1h;1!H;${;g;s/EndSection[\n \t]*Section\([^\n]*\)/EndSection\n\nSection\1/g;p;}' $1 >$TMPFILE && cp $TMPFILE $1
	if [ -f $TMPFILE ]; then rm $TMPFILE; fi
	if [ "$FBDEVVGLUSERSONLY" = "1" ]; then
		addtotop $1 "Section \\\"DRI\\\"\n\tMode 0660\n\tGroup \\\"vglusers\\\"\nEndSection"
	else
		addtotop $1 "Section \\\"DRI\\\"\n\tMode 0666\nEndSection"
	fi
}

unconfigdev()
{
	if [ "$UNAME_S" = "SunOS" ]; then
		echo ... Modifying /etc/logindevperm to enable automatic permissions for
		echo "    /dev/fbs/* ..."
		uncommentline /etc/logindevperm "\/dev\/console.*\/dev\/fbs"
	elif [ "$UNAME_S" = "Linux" ]; then
		if [ -f /etc/security/console.perms ]; then
			echo ... Modifying /etc/security/console.perms to enable automatic permissions
			echo "    for DRI devices ..."
			uncommentline /etc/security/console.perms "\<dri\>"
		fi
		if [ -f /etc/security/console.perms.d/50-default.perms ]; then
			echo ... Modifying /etc/security/console.perms.d/50-default.perms to enable automatic permissions
			echo "    for DRI devices ..."
			uncommentline /etc/security/console.perms.d/50-default.perms "\<dri\>"
		fi
		if [ -f /etc/logindevperm ]; then
			echo ... Modifying /etc/logindevperm to enable automatic permissions for
			echo "    /dev/nvidia* ..."
			uncommentline /etc/logindevperm "\/dev\/nvidia"
		fi
		if [ -f /etc/modprobe.d/virtualgl.conf -o -f /etc/modprobe.d/virtualgl ]; then
			echo ... Removing /etc/modprobe.d/virtualgl.conf to restore default permissions for
			echo "    /dev/nvidia* ..."
			rm -f /etc/modprobe.d/virtualgl
			rm -f /etc/modprobe.d/virtualgl.conf
			$LSMOD | grep -q nvidia >/dev/null 2>/dev/null
			if [ $? = 0 ]; then
				echo ... Attempting to remove nvidia module from memory so device permissions
				echo "    will be reloaded ..."
				$RMMOD nvidia || RMMODNEEDED=1
			fi
		fi
		if [ -f /etc/udev/rules.d/99-virtualgl-dri.rules ]; then
			echo ... Removing /etc/udev/rules.d/99-virtualgl-dri.rules to restore default
			echo "    permissions for /dev/dri/card0 at next boot ..."
			rm -f /etc/udev/rules.d/99-virtualgl-dri.rules
		fi
		if [ -f /etc/X11/xorg.conf.d/99-virtualgl-dri ]; then
			echo ... Removing /etc/X11/xorg.conf.d/99-virtualgl-dri to restore default
			echo "    permissions for /dev/dri/card0 ..."
			rm -f /etc/X11/xorg.conf.d/99-virtualgl-dri
		fi
	fi
}

configdev()
{
	if [ "$UNAME_S" = "SunOS" ]; then
		echo ... Modifying /etc/logindevperm to disable automatic permissions for
		echo "    /dev/fbs/* ..."
		commentline /etc/logindevperm "\/dev\/console.*\/dev\/fbs"
		chmod 755 /dev/fbs
		if [ "$FBDEVVGLUSERSONLY" = "1" ]; then
			echo ... Granting write permission to /dev/fbs/\* for vglusers group ...
			chmod 660 /dev/fbs/*
			chown root:vglusers /dev/fbs/*
		else
			echo ... Granting write permission to /dev/fbs/\* for all users ...
			chmod 666 /dev/fbs/*
			chown root:root /dev/fbs/*
		fi
	elif [ "$UNAME_S" = "Linux" ]; then
		if [ -f /etc/security/console.perms ]; then
			echo ... Modifying /etc/security/console.perms to disable automatic permissions
			echo "    for DRI devices ..."
			commentline /etc/security/console.perms "\<dri\>"
		fi
		if [ -f /etc/security/console.perms.d/50-default.perms ]; then
			echo ... Modifying /etc/security/console.perms.d/50-default.perms to disable automatic permissions
			echo "    for DRI devices ..."
			commentline /etc/security/console.perms.d/50-default.perms "\<dri\>"
		fi
		if [ -f /etc/logindevperm ]; then
			echo ... Modifying /etc/logindevperm to disable automatic permissions for
			echo "    /dev/nvidia* ..."
			commentline /etc/logindevperm "\/dev\/nvidia"
		fi
		if [ -d /etc/modprobe.d ]; then
			if [ -f /etc/modprobe.d/nvidia ]; then
				echo ... Modifying /etc/modprobe.d/nvidia to set requested permissions for
			else
				echo ... Creating /etc/modprobe.d/virtualgl.conf to set requested permissions for
			fi
			echo "    /dev/nvidia* ..."
			VGLUSERSGID=`grep vglusers /etc/group | cut -f3 -d:`
			if [ -f /etc/modprobe.d/nvidia ]; then
				if [ "$FBDEVVGLUSERSONLY" = "1" -a ! "$VGLUSERSGID" = "" ]; then
					replaceline /etc/modprobe.d/nvidia "options nvidia" "options nvidia NVreg_DeviceFileUID=0 NVreg_DeviceFileGID=$VGLUSERSGID NVreg_DeviceFileMode=0660"
				else
					replaceline /etc/modprobe.d/nvidia "options nvidia" "options nvidia NVreg_DeviceFileUID=0 NVreg_DeviceFileGID=0 NVreg_DeviceFileMode=0666"
				fi
			else
				if [ "$FBDEVVGLUSERSONLY" = "1" -a ! "$VGLUSERSGID" = "" ]; then
					echo "options nvidia NVreg_DeviceFileUID=0 NVreg_DeviceFileGID=$VGLUSERSGID NVreg_DeviceFileMode=0660" >/etc/modprobe.d/virtualgl.conf
				else
					echo "options nvidia NVreg_DeviceFileUID=0 NVreg_DeviceFileGID=0 NVreg_DeviceFileMode=0666" >/etc/modprobe.d/virtualgl.conf
				fi
				chmod 644 /etc/modprobe.d/virtualgl.conf
			fi
			$LSMOD | grep -q nvidia >/dev/null 2>/dev/null
			if [ $? = 0 ]; then
				echo ... Attempting to remove nvidia module from memory so device permissions
				echo "    will be reloaded ..."
				$RMMOD nvidia || RMMODNEEDED=1
			fi
		fi
		if [ "$FBDEVVGLUSERSONLY" = "1" ]; then
			if [ -e /dev/nvidia0 -o -e /dev/nvidiactl ]; then
				echo ... Granting write permission to /dev/nvidia* for vglusers group ...
				chmod 660 /dev/nvidia*
				chown root:vglusers /dev/nvidia*
			fi
			if [ -e /dev/dri/card0 ]; then
				echo ... Granting write permission to /dev/dri/card0 for vglusers group ...
				chmod 660 /dev/dri/card0
				chown root:vglusers /dev/dri/card0
			fi
		else
			if [ -e /dev/nvidia0 -o -e /dev/nvidiactl ]; then
				echo ... Granting write permission to /dev/nvidia* for all users ...
				chmod 666 /dev/nvidia*
				chown root:root /dev/nvidia*
			fi
			if [ -e /dev/dri/card0 ]; then
				echo ... Granting write permission to /dev/dri/card0 for all users ...
				chmod 666 /dev/dri/card0
				chown root:root /dev/dri/card0
			fi
		fi
		if [ -d /etc/udev/rules.d ]; then
			if [ "$FBDEVVGLUSERSONLY" = "1" ]; then
				echo "KERNEL==\"card[0-9]\", MODE=\"0660\", OWNER=\"root\", GROUP=\"vglusers\"" >/etc/udev/rules.d/99-virtualgl-dri.rules
			else
				echo "KERNEL==\"card[0-9]\", MODE=\"0666\", OWNER=\"root\", GROUP=\"root\"" >/etc/udev/rules.d/99-virtualgl-dri.rules
			fi
		fi
		if [ -d /etc/X11/xorg.conf.d ]; then
			touch /etc/X11/xorg.conf.d/99-virtualgl-dri
			setdripermissions /etc/X11/xorg.conf.d/99-virtualgl-dri
		fi
		setdripermissions /etc/X11/xorg.conf backup
		setdripermissions /etc/X11/XF86Config backup
	fi
}

ynprompt()
{
	if [ "$1" = "" ]; then
		echo 'USAGE: ynprompt <prompt>'
		return 0
	fi
	while [ 1 ]; do
		echo
		echo $1
		echo \[Y\/n\]
		read _CHOICE
		if [ "$_CHOICE" = "" ]; then return 1; fi
		case $_CHOICE in
			[yY]*) return 1 ;;
			[nN]*) return 0 ;;
		esac
	done
}

checkselinux()
{
	if [ ! "$UNAME_S" = "Linux" ]; then
		return 0
	fi
	if [ -f /selinux/enforce ]; then
		SELINUX=`cat /selinux/enforce`
	elif [ -f /sys/fs/selinux/enforce ]; then
		SELINUX=`cat /sys/fs/selinux/enforce`
	fi
	if [ $SELINUX != 1 ]; then
		return 0;
	fi
	if [ -x /usr/sbin/semanage ]; then
		SEMANAGE=/usr/sbin/semanage
	else
		SEMANAGE_TEMP=`which semanage 2>/dev/null`
		if [ $? = 0 ]; then
			SEMANAGE=$SEMANAGE_TEMP
		else
			echo
			echo "ERROR: SELinux is enabled, but the semanage program is not installed.  This"
			echo "program is usually contained in a package called \"policycoreutils\" or"
			echo "\"policycoreutils-python\" or \"policycoreutils-python-utils\".  On systems with"
			echo "YUM or DNF, try running \"yum install /usr/sbin/semanage\" or"
			echo "\"dnf install /usr/sbin/semanage\"."
			return 1
		fi
	fi
	if [ -x /sbin/restorecon ]; then
		RESTORECON=/sbin/restorecon
		return 0
	else
		RESTORECON_TEMP=`which restorecon 2>/dev/null`
		if [ $? = 0 ]; then
			RESTORECON=$RESTORECON_TEMP
			return 0
		else
			echo
			echo "ERROR: SELinux is enabled, but the restorecon program is not installed.  This"
			echo "program is usually contained in a package called \"policycoreutils\".  On systems"
			echo "with YUM or DNF, try running \"yum install /sbin/restorecon\" or"
			echo "\"dnf install /sbin/restorecon\"."
			return 1
		fi
	fi
}

checkwayland()
{
	which Xwayland >/dev/null 2>&1 || return 0
	if [ ! -f /etc/systemd/system/display-manager.service ]; then
		return 0
	fi
	DM=`grep ExecStart=\/usr /etc/systemd/system/display-manager.service | sed 's/.*\///g'`
	if [ ! "$DM" = "gdm" -a ! "$DM" = "gdm3" ]; then
		return 0
	fi
	WAYLAND=1
	echo
	echo WARNING: Configuring this server for use with VirtualGL will disable the
	echo ability to log in locally with a Wayland session.
	if [ $UNATTENDED = 0 ]; then
		ynprompt "Continue?"
		if [ ! "$?" = "1" ]; then
			return 1
		fi
	else
		echo
	fi
	return 0
}

unconfigglx()
{
	if [ -d /etc/opt/VirtualGL ]; then
		checkselinux || return
		echo ... Removing /etc/opt/VirtualGL directory ...
		rm /etc/opt/VirtualGL/* 2>/dev/null
		rmdir /etc/opt/VirtualGL
		if [ $SELINUX = 1 ]; then
			echo ... Removing custom SELinux contexts ...
			# Try to combine operations (semanage is slow)
			$SEMANAGE -i - <<EOF >/dev/null
fcontext -d '/etc/opt/VirtualGL(/.*)?'
fcontext -d /usr/bin/xauth
EOF
			if [ $? = 1 ]; then
				# That didn't work.  Try the old-fashioned way
				$SEMANAGE fcontext -d '/etc/opt/VirtualGL(/.*)?'
				$SEMANAGE fcontext -d /usr/bin/xauth
			fi
			$RESTORECON -R -v /usr/bin/xauth
		fi
	fi

	if [ -f /etc/X11/xdm/Xsetup_0 -a ! -h /etc/X11/xdm/Xsetup_0 ]; then
		delvglgenkey /etc/X11/xdm/Xsetup_0
	else
		if [ -f /etc/X11/xdm/Xsetup -a ! -h /etc/X11/xdm/Xsetup ]; then
			delvglgenkey /etc/X11/xdm/Xsetup
		fi
	fi
	if [ -f /etc/X11/gdm/Init/:0 ]; then
		if [ ! -h /etc/X11/gdm/Init/:0 ]; then
			delvglgenkey /etc/X11/gdm/Init/:0
		fi
	else
		if [ -f /etc/X11/gdm/Init/Default -a ! -h /etc/X11/gdm/Init/Default ]; then
			delvglgenkey /etc/X11/gdm/Init/Default
		fi
	fi
	if [ -f /etc/X11/gdm/SunRayInit/Default ]; then
		delvglgenkey /etc/X11/gdm/SunRayInit/Default
	fi
	for file in /etc/gdm/Init/Default \
		/etc/gdm3/Init/Default \
		/usr/local/etc/gdm/Init/Default \
		/etc/opt/gnome/gdm/Init/Default \
		/etc/kde4/kdm/Xsetup \
		/usr/share/config/kdm/Xsetup \
		/usr/local/kde4/share/config/kdm/Xsetup \
		/usr/share/sddm/scripts/Xsetup \
		/etc/mdm/Init/Default; do
		if [ -f $file -a ! -h $file ]; then
			delvglgenkey $file
		fi
	done
	if [ -f /etc/lightdm/lightdm.conf ]; then
		echo "... Removing X server access from /etc/lightdm/lightdm.conf ..."
		removeline /etc/lightdm/lightdm.conf display-setup-script
		removeline /etc/lightdm/lightdm.conf greeter-setup-script
	fi
	for dir in /usr/share/gdm/greeter/autostart \
		/usr/local/share/gdm/greeter/autostart; do
		if [ -f $dir/virtualgl.desktop ]; then
			echo "... Removing $dir/virtualgl.desktop ..."
			rm $dir/virtualgl.desktop
		fi
	done

	for file in /etc/gdm/custom.conf \
		/etc/X11/gdm/custom.conf \
		/etc/gdm3/custom.conf \
		/etc/gdm3/daemon.conf; do
		if [ -f $file -a ! -h $file ]; then
			echo "... Re-enabling Wayland in $file ..."
			commentline $file "WaylandEnable.*=.*false"
		fi
	done

	if [ "$UNAME_S" = "SunOS" ]; then
		if [ -f /etc/dt/config/Xsetup ]; then
			delvglgenkey /etc/dt/config/Xsetup
		fi
		if [ -f /etc/dt/config/Xconfig ]; then
			echo ... Restoring default value of Dtlogin\*grabServer in ...
			echo "...     /etc/dt/config/Xconfig ..."
			commentline /etc/dt/config/Xconfig Dtlogin\\*grabServer
		fi
		if [ -f /etc/dt/config/Xconfig.SUNWut.prototype ]; then
			echo ... Restoring default value of Dtlogin\*grabServer in ...
			echo "...     /etc/dt/config/Xconfig.SUNWut.prototype ..."
			commentline /etc/dt/config/Xconfig.SUNWut.prototype Dtlogin\\*grabServer
		fi
	fi

	for file in /etc/X11/xdm/Xservers \
		/etc/X11/gdm/gdm.conf \
		/etc/gdm/custom.conf \
		/etc/gdm3/daemon.conf \
		/usr/local/etc/gdm/custom.conf \
		/etc/gdm/gdm.conf \
		/etc/X11/gdm/custom.conf \
		/etc/opt/gnome/gdm/gdm.conf \
		/etc/opt/kde3/share/config/kdm/Xservers \
		/etc/mdm/mdm.conf; do
		if [ -f $file -a ! -h $file ]; then
			enablextest $file
		fi
	done
	if [ -f /etc/gdm/gdm-cdd.conf ]; then
		enablextest /etc/gdm/gdm-cdd.conf
	fi
	for file in /etc/kde4/kdm/kdmrc \
		/etc/kde/kdm/kdmrc \
		/usr/share/config/kdm/kdmrc \
		/usr/local/kde4/share/config/kdm/kdmrc; do
		if [ -f $file -a ! -h $file ]; then
			enablextestkdm $file
		fi
	done
	if [ "$UNAME_S" = "SunOS" ]; then
		if [ -f /etc/dt/config/Xservers ]; then
			enablextest /etc/dt/config/Xservers
		fi
		if [ -x /usr/sbin/svccfg ]; then
			/usr/sbin/svccfg -s application/x11/x11-server delpropvalue options/server_args "*-tst*" 2>&1 >/dev/null
		fi
	fi

	for file in /etc/X11/gdm/gdm.conf \
		/etc/gdm/custom.conf \
		/etc/gdm3/daemon.conf \
		/usr/local/etc/gdm/custom.conf \
		/etc/gdm/gdm.conf \
		/etc/X11/gdm/custom.conf \
		/etc/opt/gnome/gdm/gdm.conf \
		/etc/mdm/mdm.conf; do
		if [ -f $file -a ! -h $file ]; then
			disallowgdmtcp $file
		fi
	done
	if [ -f /etc/gdm/gdm-cdd.conf ]; then
		disallowgdmtcp /etc/gdm/gdm-cdd.conf
	fi

	unconfigdev

	echo
	echo Done.  You must restart the display manager for the changes to take effect.
	if [ "$RMMODNEEDED" = "1" ]; then
		echo
		echo "IMPORTANT NOTE: Your system uses modprobe.d to set device permissions.  You"
		echo "must execute 'rmmod nvidia_drm nvidia_modeset nvidia' with the display manager"
		echo "stopped in order for the new device permission settings to become effective."
	fi
	echo
}

configglx()
{
	checkwayland || return

	if [ $UNATTENDED = 0 ]; then
		ynprompt "Restrict 3D X server access to vglusers group (recommended)?"
		if [ $? = 1 ]; then VGLUSERSONLY=1; else VGLUSERSONLY=0; fi

		ynprompt "Restrict framebuffer device access to vglusers group (recommended)?"
		if [ $? = 1 ]; then FBDEVVGLUSERSONLY=1; else FBDEVVGLUSERSONLY=0; fi

		ynprompt "Disable XTEST extension (recommended)?"
		if [ $? = 1 ]; then DISABLEXTEST=1; else DISABLEXTEST=0; fi
	fi

	if [ "$VGLUSERSONLY" = "1" ]; then
		checkselinux || return
		echo ... Creating vglusers group ...
		if [ ! "$GID" = "" ]; then
			$GROUPADD -g $GID vglusers || echo "Could not add vglusers group (probably because it already exists.)"
		else
			$GROUPADD vglusers || echo "Could not add vglusers group (probably because it already exists.)"
		fi

		if [ ! -d /etc/opt/VirtualGL ]; then
			echo ... Creating /etc/opt/VirtualGL/ ...
			mkdir -p /etc/opt/VirtualGL
		fi
		echo ... Granting read permission to /etc/opt/VirtualGL/ for vglusers group ...
		getent group gdm >/dev/null 2>&1 && (
			chown gdm:vglusers /etc/opt/VirtualGL
		) || (
			getent group Debian-gdm >/dev/null 2>&1 && (
				chown Debian-gdm:vglusers /etc/opt/VirtualGL
			) || (
				chown root:vglusers /etc/opt/VirtualGL
			)
		)
		chmod 750 /etc/opt/VirtualGL
		if [ $SELINUX = 1 ]; then
			echo ... Setting SELinux contexts to allow vglgenkey to run within GDM ...
			# Try to combine operations (semanage is slow)
			$SEMANAGE -i - <<EOF >/dev/null
fcontext -a -t xdm_rw_etc_t '/etc/opt/VirtualGL(/.*)?'
fcontext -a -t xdm_exec_t /usr/bin/xauth
EOF
			if [ $? = 1 ]; then
				# That didn't work.  Try the old-fashioned way
				$SEMANAGE fcontext -a -t xdm_rw_etc_t '/etc/opt/VirtualGL(/.*)?'
				$SEMANAGE fcontext -a -t xdm_exec_t /usr/bin/xauth
			fi
			$RESTORECON -R -v /etc/opt/VirtualGL /usr/bin/xauth
		fi
	fi

	configdev

	if [ -f /etc/X11/xdm/Xsetup_0 -a ! -h /etc/X11/xdm/Xsetup_0 ]; then
		addvglgenkey /etc/X11/xdm/Xsetup_0
	else
		if [ -f /etc/X11/xdm/Xsetup -a ! -h /etc/X11/xdm/Xsetup ]; then
			addvglgenkey /etc/X11/xdm/Xsetup
		fi
	fi
	if [ -f /etc/X11/gdm/Init/:0 ]; then
		if [ ! -h /etc/X11/gdm/Init/:0 ]; then
			addvglgenkey /etc/X11/gdm/Init/:0
		fi
	else
		if [ -f /etc/X11/gdm/Init/Default -a ! -h /etc/X11/gdm/Init/Default ]; then
			addvglgenkey /etc/X11/gdm/Init/Default
		fi
	fi
	if [ -f /etc/X11/gdm/SunRayInit/Default ]; then
		addvglgenkey /etc/X11/gdm/SunRayInit/Default
	fi
	for file in /etc/gdm/Init/Default \
		/etc/gdm3/Init/Default \
		/usr/local/etc/gdm/Init/Default \
		/etc/opt/gnome/gdm/Init/Default \
		/etc/kde4/kdm/Xsetup \
		/usr/share/config/kdm/Xsetup \
		/usr/local/kde4/share/config/kdm/Xsetup \
		/usr/share/sddm/scripts/Xsetup \
		/etc/mdm/Init/Default; do
		if [ -f $file -a ! -h $file ]; then
			addvglgenkey $file
		fi
	done
	if [ -f /etc/lightdm/lightdm.conf ]; then
		addvglgenkey_lightdm /etc/lightdm/lightdm.conf
	elif [ -d /etc/lightdm ]; then
		echo [SeatDefaults] >/etc/lightdm/lightdm.conf
		addvglgenkey_lightdm /etc/lightdm/lightdm.conf
	fi
	for dir in /usr/share/gdm/greeter/autostart \
		/usr/local/share/gdm/greeter/autostart; do
		if [ -d $dir ]; then
			echo ... Creating $dir/virtualgl.desktop ...
			if [ "$VGLUSERSONLY" = "1" ]; then
				cat >$dir/virtualgl.desktop <<EOF
[Desktop Entry]
Type=Application
Exec=$VGLGENKEY
EOF
			else
				cat >$dir/virtualgl.desktop <<EOF
[Desktop Entry]
Type=Application
Exec=xhost +LOCAL:
EOF
			fi
			chmod 644 $dir/virtualgl.desktop
		fi
	done

	for file in /etc/gdm/custom.conf \
		/etc/X11/gdm/custom.conf \
		/etc/gdm3/custom.conf \
		/etc/gdm3/daemon.conf; do
		if [ -f $file -a ! -h $file -a $WAYLAND = 1 ]; then
			disablewaylandgdm $file
		fi
	done

	if [ "$UNAME_S" = "SunOS" ]; then
		if [ ! -d /etc/dt/config ]; then
			echo ... Creating /etc/dt/config/ directory ...
			mkdir -p /etc/dt/config
			chmod 755 /etc/dt/config
		fi

		if [ ! -f /etc/dt/config/Xsetup ]; then
			if [ -f /usr/dt/config/Xsetup ]; then
				echo ... Copying /usr/dt/config/Xsetup to /etc/dt/config/Xsetup ...
				cp /usr/dt/config/Xsetup /etc/dt/config/Xsetup
			fi
		else
			backup /etc/dt/config/Xsetup
		fi
		if [ -f /etc/dt/config/Xsetup ]; then
			addvglgenkey /etc/dt/config/Xsetup bottom
		fi

		if [ ! -f /etc/dt/config/Xconfig ]; then
			if [ -f /usr/dt/config/Xconfig ]; then
				echo ... Copying /usr/dt/config/Xconfig to /etc/dt/config/Xconfig ...
				cp /usr/dt/config/Xconfig /etc/dt/config/Xconfig
			fi
		else
			backup /etc/dt/config/Xconfig
		fi
		if [ -f /etc/dt/config/Xconfig ]; then
			echo ... Setting Dtlogin\*grabServer to False in /etc/dt/config/Xconfig ...
			replaceline /etc/dt/config/Xconfig Dtlogin\\*grabServer "Dtlogin\*grabServer: False"
		fi
		if [ -f /etc/dt/config/Xconfig.SUNWut.prototype ]; then
			backup /etc/dt/config/Xconfig.SUNWut.prototype
			echo ... Setting Dtlogin\*grabServer to False in /etc/dt/config/Xconfig.SUNWut.prototype ...
			replaceline /etc/dt/config/Xconfig.SUNWut.prototype Dtlogin\\*grabServer "Dtlogin\*grabServer: False"
		fi

	fi

	for file in /etc/X11/xdm/Xservers \
		/etc/X11/gdm/gdm.conf \
		/etc/gdm/custom.conf \
		/etc/gdm3/daemon.conf \
		/usr/local/etc/gdm/custom.conf \
		/etc/gdm/gdm.conf \
		/etc/X11/gdm/custom.conf \
		/etc/opt/gnome/gdm/gdm.conf \
		/etc/opt/kde3/share/config/kdm/Xservers \
		/etc/mdm/mdm.conf; do
		if [ -f $file -a ! -h $file ]; then
			if [ "$DISABLEXTEST" = "1" ]; then
				disablextest $file
			else
				enablextest $file
			fi
		fi
	done
	if [ -f /etc/gdm/gdm-cdd.conf ]; then
		if [ "$DISABLEXTEST" = "1" ]; then
			disablextest /etc/gdm/gdm-cdd.conf
		else
			enablextest /etc/gdm/gdm-cdd.conf
		fi
	fi
	for file in /etc/kde4/kdm/kdmrc \
		/etc/kde/kdm/kdmrc \
		/usr/share/config/kdm/kdmrc \
		/usr/local/kde4/share/config/kdm/kdmrc; do
		if [ -f $file -a ! -h $file ]; then
			if [ "$DISABLEXTEST" = "1" ]; then
				disablextestkdm $file
			else
				enablextestkdm $file
			fi
		fi
	done
	if [ "$UNAME_S" = "SunOS" ]; then
		if [ "$DISABLEXTEST" = "1" ]; then
			if [ ! -f /etc/dt/config/Xservers ]; then
				if [ -f /usr/dt/config/Xservers ]; then
					echo ... Copying /usr/dt/config/Xservers to /etc/dt/config/Xservers ...
					cp /usr/dt/config/Xservers /etc/dt/config/Xservers
				fi
			fi
			if [ -f /etc/dt/config/Xservers ]; then
				disablextest /etc/dt/config/Xservers
			fi
			if [ -x /usr/sbin/svccfg ]; then
				/usr/sbin/svccfg -s application/x11/x11-server delpropvalue options/server_args "*-tst*" 2>&1 >/dev/null
				/usr/sbin/svccfg -s application/x11/x11-server addpropvalue options/server_args -tst 2>&1 >/dev/null
			fi
		else
			if [ -f /etc/dt/config/Xservers ]; then
				enablextest /etc/dt/config/Xservers
			fi
			if [ -x /usr/sbin/svccfg ]; then
				/usr/sbin/svccfg -s application/x11/x11-server delpropvalue options/server_args "*-tst*" 2>&1 >/dev/null
			fi
		fi
	fi

	if [ "$UNAME_S" = "Linux" ]; then
		if [ -f /etc/inittab ]; then
			echo ... Setting default run level to 5 \(enabling graphical login prompt\) ...
			replaceline /etc/inittab "id:[0-9]:initdefault:" "id:5:initdefault:"
		fi
	fi

	for file in /etc/X11/gdm/gdm.conf \
		/etc/gdm/custom.conf \
		/etc/gdm3/daemon.conf \
		/usr/local/etc/gdm/custom.conf \
		/etc/gdm/gdm.conf \
		/etc/X11/gdm/custom.conf \
		/etc/opt/gnome/gdm/gdm.conf \
		/etc/mdm/mdm.conf; do
		if [ -f $file -a ! -h $file ]; then
			disallowgdmtcp $file
		fi
	done
	if [ -f /etc/gdm/gdm-cdd.conf ]; then
		disallowgdmtcp /etc/gdm/gdm-cdd.conf
	fi

	echo
	echo Done.  You must restart the display manager for the changes to take effect.
	if [ "$RMMODNEEDED" = "1" ]; then
		echo
		echo "IMPORTANT NOTE: Your system uses modprobe.d to set device permissions.  You"
		echo "must execute 'rmmod nvidia_drm nvidia_modeset nvidia' with the display manager"
		echo "stopped in order for the new device permission settings to become effective."
	fi
	echo
}

MYPATH=$(dirname "$(realpath "$0")")
if [ -x $MYPATH/vglgenkey ]; then
	VGLGENKEY=$MYPATH/vglgenkey
else
	echo The vglgenkey script must be in the same directory as vglserver_config and must be executable.
	exit 1
fi

while [ $# -gt 0 ]; do
	case "$1" in
		-s) VGLUSERSONLY=1 ;;
		-f) FBDEVVGLUSERSONLY=1 ;;
		-t) DISABLEXTEST=1 ;;
		+s) VGLUSERSONLY=0 ;;
		+f) FBDEVVGLUSERSONLY=0 ;;
		+t) DISABLEXTEST=0 ;;
		-gid) GID=$2; shift ;;
		+glx) CONFIG_VGL="configglx"; UNATTENDED=1 ;;
		-glx) CONFIG_VGL="unconfigglx"; UNATTENDED=1 ;;
		-config) CONFIG_VGL="configglx"; UNATTENDED=1 ;;
		-unconfig) CONFIG_VGL="unconfigglx"; UNATTENDED=1 ;;
		*) usage 0
	esac
	shift
done

if [ "$CONFIG_VGL" = "" -a $UNATTENDED = 1 ]; then
	usage 0
fi

UNAME_S=`uname -s`
UNAME_M=`uname -m`

if [ ! `uid` -eq 0 ]; then
	echo This script can only be executed by the root user.
	exit 1
fi

if [ $UNATTENDED = 0 ]; then
	while [ 1 ]
	do
		echo
		echo "1) Configure server for use with VirtualGL"
		echo "2) Unconfigure server for use with VirtualGL"
		echo "X) Exit"
		echo
		echo Choose:
		read _CHOICE

		case $_CHOICE in
		1) configglx
			;;
		2) unconfigglx
			;;
		X) break
			;;
		x) break
			;;
			esac
	done
else
	$CONFIG_VGL
fi
