#!/bin/sh
# Copyright (C) 2005-2016 Weijie Gao <hackpascal@gmail.com>

. $IPKG_INSTROOT/lib/functions.sh

output_field()
{
	local UCI_SECTION=$1
	local KEY=$2
	local INIFIELD=$3
	local DEFVALUE=$4
	local value

	if [ -z "$INIFIELD" ]; then INIFIELD=$KEY; fi

	config_get value "$UCI_SECTION" "$KEY"
	if [ -z "$value" ]; then value=$DEFVALUE; fi

	echo "$INIFIELD=$value" >> $CONF
}

output_bool()
{
	local UCI_SECTION=$1
	local KEY=$2
	local INIFIELD=$3
	local DEFVALUE=$4
	local value

	if [ -z "$INIFIELD" ]; then INIFIELD=$KEY; fi

	config_get value "$UCI_SECTION" "$KEY"
	if [ -z "$value" ]; then value=$DEFVALUE; fi
	if [ x"$value" != x0 ] && [ x"$value" != x1 ]; then value=0; fi

	if [ "$value" == 0 ]; then
		value=NO
	else
		value=YES
	fi

	echo "$INIFIELD=$value" >> $CONF
}

output_const()
{
	local INIFIELD=$1
	local value=$2

	echo "$INIFIELD=$value" >> $CONF
}

get_value()
{
	local UCI_SECTION=$1
	local KEY=$2
	local value

	config_get value "$UCI_SECTION" "$KEY"

	echo $value
}

vusers_iterate()
{
	local config=$1
	local name
	local password
	local owner
	local home
	local _umask
	local maxrate
	local write_enable
	local upload_enable
	local mkdir_enable
	local others_enable

	config_get name "$config" username
	config_get password "$config" password
	config_get home "$config" home
	config_get _umask "$config" "umask"
	config_get maxrate "$config" maxrate
	config_get write_enable "$config" writemkdir
	config_get upload_enable "$config" upload
	config_get others_enable "$config" others

	config_get owner "vuser" username

	rm -f $VUSER_CONF_DIR/$name
	touch $VUSER_CONF_DIR/$name

	if [ -z $home ]; then home=$CHROOT_DIR; fi

	echo "local_root=$home" >> $VUSER_CONF_DIR/$name

	if [ x$write_enable = x1 ]; then write_enable=YES; else write_enable=NO; fi
	if [ x$upload_enable = x1 ]; then upload_enable=YES; else upload_enable=NO; fi
	if [ x$others_enable = x1 ]; then others_enable=YES; else others_enable=NO; fi
	if [ -z $_umask ]; then _umask=022; fi
	if [ -z $maxrate ]; then maxrate=0; fi

	echo "anon_world_readable_only=NO" >> $VUSER_CONF_DIR/$name
	echo "anon_mkdir_write_enable=$write_enable" >> $VUSER_CONF_DIR/$name
	echo "write_enable=$write_enable" >> $VUSER_CONF_DIR/$name
	echo "anon_upload_enable=$upload_enable" >> $VUSER_CONF_DIR/$name
	echo "anon_other_write_enable=$others_enable" >> $VUSER_CONF_DIR/$name
	echo "anon_umask=$_umask" >> $VUSER_CONF_DIR/$name
	echo "anon_max_rate=$maxrate" >> $VUSER_CONF_DIR/$name

	if ! [ -d "$home" ]; then
		mkdir -p $home
		chown $owner:$owner $home
		chmod -R a+w $home
	fi
}

VAR=/var/run/vsftpd
CONF=$VAR/vsftpd.conf
VUSER_DB=$VAR/vusers
VUSER_CONF_DIR=$VAR/users
CHROOT_DIR=$VAR/empty

rm -f $CONF
rm -rf $VUSER_CONF_DIR $CHROOT_DIR

mkdir -m 0755 -p $VAR
mkdir -p $VUSER_CONF_DIR
mkdir -p $CHROOT_DIR

config_load vsftpd

# listen
output_const "background" YES
output_field listen port "listen_port" 21
output_field listen dataport "ftp_data_port" 20
output_field listen pasv_min_port "pasv_min_port" 50000
output_field listen pasv_max_port "pasv_max_port" 51000

# global
output_bool global 'write' "write_enable" 1
output_bool global download "download_enable" 1
output_bool global dirlist "dirlist_enable" 1
output_bool global lsrecurse "ls_recurse_enable"
output_bool global dotfile "force_dot_files"
output_field global 'umask' "local_umask" 022

ftpd_banner=`get_value global banner`
if ! [ -z $ftpd_banner ]; then
	output_const "ftpd_banner" $ftpd_banner
fi

output_bool global dirmessage "dirmessage_enable"
output_field global dirmsgfile "message_file" ".message"

# connection
output_bool connection portmode "port_enable" 1
output_bool connection pasvmode "pasv_enable" 1

ascii_download_enable=NO
ascii_upload_enable=NO
case `get_value connection ascii` in
download)
	ascii_download_enable=YES
;;
upload)
	ascii_upload_enable=YES
;;
both)
	ascii_download_enable=YES
	ascii_upload_enable=YES
esac
output_const "ascii_download_enable" $ascii_download_enable
output_const "ascii_upload_enable" $ascii_upload_enable

output_field connection idletimeout "idle_session_timeout" 1800
output_field connection conntimeout "connect_timeout" 120
output_field connection dataconntimeout "data_connection_timeout" 120
output_field connection maxclient "max_clients" 0
output_field connection maxperip "max_per_ip" 0
output_field connection maxrate "local_max_rate" 0

max_login_fails=`get_value connection maxretry`
if [ -z $max_login_fails ] || [ $max_login_fails -lt 1 ]; then max_login_fails=3; fi
output_const "max_login_fails" $max_login_fails

# anonymous
ftp_username=`get_value anonymous ftp_username`
if [ -z $ftp_username ]; then ftp_username="ftp"; fi
output_const "ftp_username" $ftp_username

mkdir -m 0755 -p /home/$ftp_username
chown $ftp_username:$ftp_username /home/$ftp_username

output_const "anon_world_readable_only" NO

anon_enable=`get_value anonymous enabled`
if [ x$anon_enable = x1 ]; then
	anon_root=`get_value anonymous root`
	if [ -z $anon_root ]; then anon_root="/home/ftp"; fi

	output_const "anonymous_enable" YES
	output_const "no_anon_password" YES
	output_const "anon_root" $anon_root
	output_field anonymous 'umask' "anon_umask" 022
	output_field anonymous maxrate "anon_max_rate" 0
	output_bool anonymous writemkdir "anon_mkdir_write_enable" 0
	output_bool anonymous upload "anon_upload_enable" 0
	output_bool anonymous others "anon_other_write_enable" 0

	mkdir -p $anon_root
	chown -R $ftp_username:$ftp_username $anon_root
else
	output_const "anonymous_enable" NO
fi

# log
output_bool log syslog "syslog_enable" 0
output_bool log xreflog "xferlog_enable" 0
output_field log 'file' "vsftpd_log_file" 0

# users
vuser_enabled=0
if [ x`get_value vuser enabled` = x1 ]; then
	vuser_enabled=1

	output_const "guest_enable" YES
	output_field vuser username "guest_username" ftp

	output_const "uci_config_name" vsftpd
	output_const "user_config_dir" "/var/run/vsftpd/users"

	config_foreach vusers_iterate user
fi

# local user
output_const "allow_writeable_chroot" YES
output_const "secure_chroot_dir" $CHROOT_DIR

local_root=$(get_value 'local' root)
if ! [ -z $local_root ]; then
	output_const "local_root" $local_root
fi

local_enable=`get_value 'local' enabled`
if [ x$local_enable = x1 ]; then
	output_const "local_enable" YES
else
	if [ $vuser_enabled = 1 ]; then
		output_const "local_enable" YES
	else
		output_const "local_enable" NO
	fi
fi

output_const "seccomp_sandbox" NO
output_const "use_localtime" YES

exit 0
