#!/bin/sh
. /etc/control.d/functions

setup_mail_spool() { # SERVER
  case "$1" in
    postfix)	# postfix, use postconf
	  MAILSPOOL="$(postconf mail_spool_directory)"
	  MAILSPOOL="${MAILSPOOL##* }"
	  test -z "$MAILSPOOL" &&
	    echo_error "Cannot find postfix mail_spool_directory" ||
	  test -d "$MAILSPOOL" || 
	  { echo_error "'$MAILSPOOL' is not a directory"; MAILSPOOL=""; }
      ;;
    "")		#	No SMTP server found	
	  echo_error "WARNING: Cannot determine current SMTP server"
      ;;
    *)		#	Unsupported SMTP server	
	  echo_error "WARNING: SMTP server '$1' is unsupported"
      ;;
  esac

  test -z "$MAILSPOOL" && {
    test -f "$MAIL" && MAILSPOOL="$(dirname "$MAIL")" || MAILSPOOL="/var/mail"
    echo_error "Assuming $MAILSPOOL mail spool"
  } || :
}

# Count number of "_"s
__argsnum() { echo $#; }
underscore_count() { local IFS="_"; __argsnum $*; }
# TODO: "validate" conflicts with xmlbeans-scripts :(
__validate() { local V=validate; $V "$@"; }

# TODO *fmodes and new_subst_add functions to move into /etc/control.d/functions

# find -printf Format must be equal to Status
new_fmodes() {	# Name Format Status
  register "$1"
  test "`underscore_count "$2"`" = "`underscore_count "$3"`" || {
    echo_error "INTERNAL ERROR: mode $3 does not correspond format $2"
    return 1
  }
  define NAME_TO_STATUS "$1" "$2"
  define NAME_TO_FORMAT "$1" "$3"
}

# Check if all files in Directory have identical status Format (default is %m_%u_%g)
# Print status or return -1
stat_files() { # Directory [Format]
    local DIR="$1" STATUS="${2:-%m_%u_%g}"
    test -d "$DIR" || { echo_error "ERROR: '$DIR' is not a directory"; return -1; }
    RET="$(find "$DIR/" -maxdepth 1 -type f -printf "@$STATUS\n" | uniq | head -2)"
    case "$RET" in
      @*@*|""|[^@]*) return -1;;
      *) printf "%s" "${RET#@}";;
    esac
}

# Show status of Directory files
control_fmodes_status() { # Directory
  local FORMAT STATUS RET
  for NAME in $NAME_LIST; do
    lookup FORMAT NAME_TO_FORMAT "$NAME"
    RET="$(stat_files "${1:?Improper empty control_fmodes_status call}" "$FORMAT")" || continue
    lookup STATUS NAME_TO_STATUS "$NAME"
    test "$STATUS" != "$RET" || { echo $NAME; return; }
  done
  echo "unknown"
}

# Set staut of files in Directory to Status according to Format
control_fmodes_set() { # Format Status Directory
  local FORMAT="$1_" STATUS="$2_"
  local DIR="${3:?Improper 3rd parameter to control_fmodes_set}" F= S= 
  while test -n "${FORMAT%_}"; do
    F="${FORMAT%%_*}"; S="${STATUS%%_*}"
    case "$F" in
      %u) find "$DIR"/ -maxdepth 1 -type f -exec chown "$S" {} \; ;;
      %g) find "$DIR"/ -maxdepth 1 -type f -exec chgrp "$S" {} \; ;;
      %m) find "$DIR"/ -maxdepth 1 -type f -exec chmod "$S" {} \; ;;
      *) echo_error "INTERNAL ERROR: unknown format" "$F";;
    esac
    FORMAT="${FORMAT#*_}"; STATUS="${STATUS#*_}";
  done
}

control_fmodes() { # Directory
	local DIR="$1" REQUEST="$2" FORMAT STATUS

	case "$REQUEST" in
	help|'help '*)
		control_help "${REQUEST#help}"
		;;
	list)
		control_list
		;;
	summary)
		control_summary
		;;
	status)
	  	control_fmodes_status "$DIR"
		;;
	*)
	  	if __validate "$REQUEST"; then
		  lookup FORMAT NAME_TO_FORMAT "$REQUEST"
		  lookup STATUS NAME_TO_STATUS "$REQUEST"
		fi
		control_fmodes_set "$FORMAT" "$STATUS" "$DIR"
		;;
	esac
}

# new_subst variant
#  - searching $Search$Value
#  - deleting $Search and adding $Add$Value after Context (default EOF)
new_subst_add() { # Name Search Value Add Context [Divider]
  local Name="$1" Search="$2" Value="$3" Add="$4"
  local Context="${5:-\$}" Divider="${6:-/}"
  new_subst $Name \
"$Search$Value" \
"
${Context}a\
$Add$Value
${Divider}$Search${Divider}d
"
}

# Detect smtp server
# TODO: this doesn't work while installing :((
##SERVER="$(rpmquery --queryformat '%{NAME}' --whatprovides smtpd)"
SERVER=postfix
# TODO: exim, gsmtpd, sendmail etc.
MGROUP=mail
CONFIG="/etc/default/useradd"
MAILSPOOL=""

setup_mail_spool "$SERVER"

new_summary "Create and access $MAILSPOOL mailboxes"

new_fmodes private 600 "%m"
new_subst_add private \
  '^[[:space:]]*CREATE_MAIL_SPOOL[[:space:]]*=[[:space:]]*' \
  'private' \
  'CREATE_MAIL_SPOOL=' \
  '$'

new_fmodes mailgrp 660_mail "%m_%g"
new_subst_add mailgrp \
  '^[[:space:]]*CREATE_MAIL_SPOOL[[:space:]]*=[[:space:]]*' \
  'yes' \
  'CREATE_MAIL_SPOOL=' \
  '$'

new_fmodes none "" ""
new_subst_add none \
  '^[[:space:]]*CREATE_MAIL_SPOOL[[:space:]]*=[[:space:]]*' \
  'no' \
  'CREATE_MAIL_SPOOL=' \
  '$'

new_help private "Only owner can access its' mailbox in $MAILSPOOL"
new_help mailgrp "Mailboxes in $MAILSPOOL are readable and writable by '$MGROUP' group"
new_help none "Mail subsystem creates mailboxes automatically"

case "$*" in
  status|'')
	STATUS="`control_fmodes "$MAILSPOOL" status`" || exit 1
	STATUS2="`control_subst "$CONFIG" status`" || :
	test "$STATUS2" != "none" || STATUS="none"
	if [ "$STATUS" != "$STATUS2" -a \( "$STATUS" != "mailgrp" -o "$STATUS2" != "unknown" \) ]; then
	  echo_error "WARNING: mixed status $STATUS/$STATUS2"
	  STATUS="unknown"
	fi
	echo "$STATUS"
	;;
  *)	if is_builtin_mode "$*"; then
		control_fmodes "$MAILSPOOL" "$*" || exit 1
	else
		control_fmodes "$MAILSPOOL" "$*" && {
		control_subst "$CONFIG" "$*"; }
	fi
	;;
esac
