#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2008 OpenWrt.org

START=90
USE_PROCD=1

PID_FILE="/var/run/stunnel.pid"
CONF_FILE="/tmp/stunnel.conf"
BIN="/usr/bin/stunnel"
SERVICE_SECTION_FOUND=0

global_defs() {
	local debug compression

	config_get alt_config_file 'globals' alt_config_file
	[ -z "$alt_config_file" ] || return 0

	# Set default settings
	printf "foreground = yes\n" >> "$CONF_FILE"
	printf "pid = %s\n" "$PID_FILE" >> "$CONF_FILE"
	printf "syslog = yes\n" >> "$CONF_FILE"

	config_get debug 'globals' debug '5'
	printf "debug = %s\n" "$debug" >> "$CONF_FILE"

	config_get compression 'globals' compression
	[ -z "$compression" ] || printf "compression = %s\n" "$compression" >> "$CONF_FILE"
}

print_options() {
	local config=$1
	shift
	for opt in "$@"; do
		local $opt
		local value
		local is_boolean=0

		if [ "${opt:0:5}" == "bool_" ]; then
			opt="${opt:5}"
			is_boolean=1
		fi

		config_get "value" "$config" "$opt"
		[ -z "$value" ] || {
			if [ "$value" = '1' ] && [ "$is_boolean" -eq "1" ]; then
				value="yes"
			elif [ "$value" = '0' ] && [ "$is_boolean" -eq "1" ] ; then
				value="no"
			fi
			printf "%s = %s\n" "$opt" "$value" >> "$CONF_FILE"
		}
	done
}

print_list() {
	local config=$1
	shift
	for opt in "$@"; do
		local $opt
		local elements
		config_get "elements" "$config" "$opt"
		for element in $elements; do
			printf "%s = %s\n" "$opt" "$element" >> "$CONF_FILE"
		done
	done
}

print_list_colon() {
	local config=$1
	local value
	shift
	for opt in "$@"; do
		local $opt
		local elements
		config_get "elements" "$config" "$opt"
		for element in $elements; do
			value="${value}:${element}"
		done
		printf "%s = %s\n" "$opt" "${value#*:}" >> "$CONF_FILE"
	done
}

service_section() {
	local cfg="$1"
	local accept_host accept_port enabled

	config_get_bool enabled "$cfg" 'enabled' '1'
	[ ${enabled} -gt 0 ] || return 0

	SERVICE_SECTION_FOUND=1
	printf "\n" >> "$CONF_FILE"
	printf "[%s]\n" "$cfg" >> "$CONF_FILE"

	config_get accept_host "$cfg" accept_host 'localhost'
	config_get accept_port "$cfg" accept_port
	printf "accept = %s:%s\n" "$accept_host" "$accept_port" >> "$CONF_FILE"

	print_options "$cfg" CApath \
		CAfile \
		cert \
		CRLpath \
		CRLfile \
		curve \
		logId \
		debug \
		engineId \
		engineNum \
		failover \
		ident \
		key \
		local \
		PSKidentity \
		PSKsecrets \
		sslVersion \
		TIMEOUTbusy \
		TIMEOUTclose \
		TIMEOUTconnect \
		TIMEOUTidle \
		bool_delay \
		bool_libwrap \
		bool_reset \
		bool_requireCert \
		bool_verifyChain \
		bool_verifyPeer \
		bool_client

	print_list "$cfg" checkEmail \
		checkHost \
		checkIP \
		connect \
		options

	print_list_colon "$cfg" ciphers
}

process_config() {
	local alt_config_file

	rm -f "$CONF_FILE"

	# First line
	printf "; STunnel configuration file generated by uci\n" > "$CONF_FILE"
	printf "; Written %s\n\n" "$(date +'%c')" >> "$CONF_FILE"

	[ -f /etc/config/stunnel ] || return 0

	config_load stunnel
	global_defs

	# If "alt_config_file" specified, use that instead
	[ -n "$alt_config_file" ] && [ -f "$alt_config_file" ] && {
		rm -f "$CONF_FILE"
		# Symlink "alt_config_file" since it's a bit easier and safer
		ln -s "$alt_config_file" "$CONF_FILE"
		# Set section found to start service user hopfully knows what you does
		SERVICE_SECTION_FOUND=1
		return 0
	}

	config_foreach service_section service
}

service_triggers() {
	procd_add_reload_trigger "stunnel"
}

start_service() {
	process_config

	if [ "$SERVICE_SECTION_FOUND" = 1 ]; then
		procd_open_instance
		procd_set_param command "$BIN"
		procd_append_param command "$CONF_FILE"
		procd_set_param respawn
		procd_set_param file "$CONF_FILE"
		procd_close_instance
	else
		logger -t stunnel -p daemon.info "No uci service section enabled or found!"
	fi
}