# These functions are used by the smtpserver to do synchronous address checking.

quadprint (quad) {

#| This is a prettyprinter for address quads.  What it prints is what someone
#| doing a VRFY or EXPN query to the SMTP server will see.

	local text user user2

	user="$(user $quad)"
	case $(channel $quad) in
	local)	ssift "$(dequote "$user")" in
		[|/].*	text="250 local delivery for"
			break
			;;
		.*
			ssift "$user" in
			(.*)@([^@]+)	# FQDN format address ?
				user="\1" ;;
			.*	;;
			tfiss

			ssift "$user" in
			(.*)\+(.*)	# A "+" in the name ?
				user="\1" ;;
			.*	;;
			tfiss

			text="$(login2uid "$user")"	# ignore return value
			if text="$(fullname "$user")"; then
				text="250 $text"
			else
				if text="$(fullname "$(recase -l "$user")")"; then
					text="250 $text"
				else
					text="550 no such user:"
				fi
			fi
			;;
		tfiss
		;;
	usenet)	text="250 newsgroup:"
		;;
	error)	case "$(host $quad)" in
		-|'')	text="550 Error" ;;
		*)	text="550 Error $(host $quad) for" ;;
		esac
		;;
	*)	text="$(channel $quad) delivery"
		case "$(host $quad)" in
		-|'')	text="250 $text for" ;;
		*)	text="250 $text to $(host $quad) for" ;;
		esac
		;;
	esac
	echo "$text <$user>"
}

server (key) {

#| The smtpserver program starts the router in interactive mode and runs this
#| function to interface with the rest of the configuration code.  The key
#| specifies the semantics of the additional arguments provided by the
#| smtpserver.  The key values are: init, to, from, verify, and expand.

	local a A B Ei Ej

	A=$(newattribute default_attributes type sender)
	B=$(newattribute default_attributes type expandsender)

#| In doing a VRFY operation, it is not desired to do any alias expansion.
#| This can be avoided by modifying the attributes of default_attributes to
#| shortcircuit alias expansion.  It is assumed that default_attributes is
#| otherwise proper for the purpose.  The value specified for the privilege
#| level should be appropriate.

	case "$key" in
	from)
		if [ "$1" = "" ]; then
			echo "250 Ok (sourcechannel 'error' accepted)"
			return
		fi
		;;
	esac

	case "$key" in
	to|from|verify|expand)
		a="$1"
		ssift "$a" in # "Defocus" brackets
		<(.+)>	a="\1"; continue ;;
		tfiss
		if rfc822syntax "$a"; then ; else
			echo "554 illegal address syntax: <$a>"
			return
		fi
		;;
	esac

	case "$key" in
	init)	# If you want to log incoming connections, it can be done here
		#echo server $@ >> /tmp/server
		# redefine the log function
		log () {
		}
		;;
	to|from)
		a="$(router "$a" default_attributes)"
		for i in $(elements $a)
		do
			for j in $(elements $i)
			do
				case $(channel $j) in
				error)	echo "554 unresolvable address: <$1>"
					return ;;
				esac

#| If any of the addresses in the expansion gave errors, we reject the
#| original address.  The lack of distinction between different kinds of errors
#| may be inadequate in some situations.

			done
		done
		echo "250 Ok (verified)"
		;;
	verify)
		a="$(router "$a" $A)"
#| Invoke the router function with alias expansion turned off.
		for i in $(elements $a)
		do
			for j in $(elements $i)
			do
				quadprint $j
			done
		done
		# echo "252 VRFY completed"
		;;
	expand)
		a="$(router "$a" $B)"

#| Invoke the router function with alias expansion enabled.

		for i in $(elements $a)
		do
			for j in $(elements $i)
			do
				quadprint $j
			done
		done
		# echo "252 EXPN completed"
		;;
	esac
}

