#!/bin/sh
#
# This file is part of OpenMediaVault.
#
# @license   http://www.gnu.org/licenses/gpl.html GPL Version 3
# @author    Volker Theile <volker.theile@openmediavault.org>
# @copyright Copyright (c) 2009-2017 Volker Theile
#
# OpenMediaVault is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# OpenMediaVault 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
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with OpenMediaVault. If not, see <http://www.gnu.org/licenses/>.

set -e

. /etc/default/openmediavault
. /usr/share/openmediavault/scripts/helper-functions

OMV_NETATALK_AFP_CONFIG=${OMV_NETATALK_AFP_CONFIG:-"/etc/netatalk/afp.conf"}
OMV_NETATALK_AFP_GUEST=${OMV_NETATALK_AFP_GUEST:-"nobody"}
OMV_NETATALK_AFP_SHARE_FILEPERM=${OMV_NETATALK_AFP_SHARE_FILEPERM:-"0664"}
OMV_NETATALK_AFP_SHARE_DIRECTORYPERM=${OMV_NETATALK_AFP_SHARE_DIRECTORYPERM:-"0775"}
OMV_NETATALK_AFP_SHARE_UMASK=${OMV_NETATALK_AFP_SHARE_UMASK:-"0002"}

[ "$(omv_config_get "//services/afp/enable")" = "0" ] && exit 0

index=$(omv_config_get_count "//services/afp/shares/share")
while [ ${index} -gt 0 ]; do
	# Get the UUID of the current share.
	uuid=$(omv_config_get "//services/afp/shares/share[position()=${index}]/uuid")
	# Process enabled shares.
	enabled=$(omv_config_get "//services/afp/shares/share[uuid='${uuid}']/enable")
	if [ "${enabled}" = "1" ]; then
		# Get the shared folder reference and path.
		sfref=$(omv_config_get "//services/afp/shares/share[uuid='${uuid}']/sharedfolderref")
		sfpath=$(omv_get_sharedfolder_path "${sfref}")

		xmlstarlet sel -t -m "//services/afp/shares/share[uuid='${uuid}']" \
		  -o "[" ${OMV_XMLSTARLET_GET_SHAREDFOLDER_NAME} -o "]" -n \
		  -o "path = ${sfpath}" -n \
		  -i "options[ro = '0']" -o "read only = no" -n -b \
		  -i "options[ro = '1']" -o "read only = yes" -n -b \
		  -i "options[upriv = '0']" -o "unix priv = no" -n -b \
		  -i "options[upriv = '1']" \
		    -o "unix priv = yes" -n \
		    -o "file perm = ${OMV_NETATALK_AFP_SHARE_FILEPERM}" -n \
		    -o "directory perm = ${OMV_NETATALK_AFP_SHARE_DIRECTORYPERM}" -n \
		    -o "umask = ${OMV_NETATALK_AFP_SHARE_UMASK}" -n \
		  -b \
		  -i "options[invisibledots = '0']" -o "invisible dots = no" -n -b \
		  -i "options[invisibledots = '1']" -o "invisible dots = yes" -n -b \
		  -i "options[tm = '0']" -o "time machine = no" -n -b \
		  -i "options[tm = '1']" -o "time machine = yes" -n -b \
		  -i "string-length(password) > 0" -v "concat('password = ',password)" -n -b \
		  -i "volsizelimit > 0" -v "concat('vol size limit = ',volsizelimit)" -n -b \
		  -i "not(casefold[. = 'none'])" -v "concat('casefold = ',casefold)" -n -b \
		  ${OMV_CONFIG_FILE} | xmlstarlet unesc >> ${OMV_NETATALK_AFP_CONFIG}

		# Process the share privileges. Users with '0 = no permission' are added
		# to 'invalid users' (to deny access), users with '5 = read and execute'
		# are added to the 'read list'.
		validusers=""
		invalidusers=""
		readlist=""
		writelist=""

		# Get shared folder user privileges.
		privileges=$(xmlstarlet sel -t -m "//system/shares/sharedfolder[uuid='${sfref}']/privileges/privilege[type='user']" \
		  -v "concat(perms,':',name)" -n \
		  ${OMV_CONFIG_FILE} | xmlstarlet unesc)
		IFS="$(printf '\n+')"
		for privilege in ${privileges}; do
			[ -z "${privilege}" ] && continue
			perms=${privilege%:*}
			name=${privilege#*:}
			# Append user to list
			case ${perms} in
			0)	[ -n "${invalidusers}" ] && invalidusers="${invalidusers} ";
				invalidusers="${invalidusers}\"${name}\"";;
			5)
				[ -n "${readlist}" ] && readlist="${readlist} ";
				readlist="${readlist}\"${name}\"";
				[ -n "${validusers}" ] && validusers="${validusers} ";
				validusers="${validusers}\"${name}\"";;
			7)
				[ -n "${writelist}" ] && writelist="${writelist} ";
				writelist="${writelist}\"${name}\"";
				[ -n "${validusers}" ] && validusers="${validusers} ";
				validusers="${validusers}\"${name}\"";;
			esac
		done
		unset IFS

		# Get shared folder group privileges.
		privileges=$(xmlstarlet sel -t -m "//system/shares/sharedfolder[uuid='${sfref}']/privileges/privilege[type='group']" \
		  -v "concat(perms,':',name)" -n \
		  ${OMV_CONFIG_FILE} | xmlstarlet unesc)
		IFS="$(printf '\n+')"
		for privilege in ${privileges}; do
			[ -z "${privilege}" ] && continue
			perms=${privilege%:*}
			name=${privilege#*:}
			# Append group to list
			case ${perms} in
			0)	[ -n "${invalidusers}" ] && invalidusers="${invalidusers} ";
				invalidusers="${invalidusers}@\"${name}\"";;
			5)
				[ -n "${readlist}" ] && readlist="${readlist} ";
				readlist="${readlist}@\"${name}\"";
				[ -n "${validusers}" ] && validusers="${validusers} ";
				validusers="${validusers}@\"${name}\"";;
			7)
				[ -n "${writelist}" ] && writelist="${writelist} ";
				writelist="${writelist}@\"${name}\"";
				[ -n "${validusers}" ] && validusers="${validusers} ";
				validusers="${validusers}@\"${name}\"";;
			esac
		done
		unset IFS

		# Process the guest account.
		if [ "$(omv_config_get "//services/afp/shares/share[uuid='${uuid}']/allowguest")" = "1" ]; then
			validusers="${validusers} \"${OMV_NETATALK_AFP_GUEST}\""
			if [ "$(omv_config_get "//services/afp/shares/share[uuid='${uuid}']/guestrw")" = "1" ]; then
				writelist="${writelist} \"${OMV_NETATALK_AFP_GUEST}\""
			else
				readlist="${readlist} \"${OMV_NETATALK_AFP_GUEST}\""
			fi
		fi

		xmlstarlet sel -t -m "//services/afp/shares/share[uuid='${uuid}']" \
		  -o "valid users = ${validusers}" -n \
		  -o "invalid users = ${invalidusers}" -n \
		  -o "rolist = ${readlist}" -n \
		  -o "rwlist = ${writelist}" -n \
		  ${OMV_CONFIG_FILE} | xmlstarlet unesc >> ${OMV_NETATALK_AFP_CONFIG}

		# Add extra options.
		xmlstarlet sel -t -m "//services/afp/shares/share[uuid='${uuid}']" \
		  -i "string-length(extraoptions) > 0" -v extraoptions -n -b \
		  ${OMV_CONFIG_FILE} | xmlstarlet unesc >> ${OMV_NETATALK_AFP_CONFIG}
	fi
	index=$(( ${index} - 1 ))
done
