#!/bin/sh
#-*- tab-width: 4; -*-
# ex:ts=4

pop()
{
	eval echo \"\${${1}}\" | head -1
}

poped()
{
	eval echo \"\${${1}}\" | sed -nEe '2,$p'
}

conv_date_fmt()
{
	local __tz __time __sign __hour=0 __min=0 __arg_utc='' \
		__date __src_fmt __dest_fmt

	case $1 in
	-u)
		shift
		__tz=$1
		__time=`env LANG=C date -j -f "%Z" "${__tz}" "+%z"`
		__sign=${__time%%[0-9]*}
		__time=${__time#${__sign}}
		__hour=${__time%[0-9][0-9]}
		__min=${__time#[0-9][0-9]}
		case ${__sign} in
		+)
			__sign='-'
			;;
		-)
			__sign='+'
			;;
		esac
		__arg_utc="-v${__sign}${__hour}H -v${__sign}${__min}M"
		shift
		;;
	*)
		;;
	esac
	__date=$1
	__src_fmt=$2
	__dest_fmt=$3
	env LANG=C date ${__arg_utc} -j -f "${__src_fmt}" "${__date}" "+${__dest_fmt}"
}

putime()
{
	local __time_now __option=$1 __key=$2 __time_start __time_end __time_int \
		__sec __min __hr __time_log_file

	__key=`echo "$2" | sed -Ee 's/[-.]/_/g'`
	__time_now=`env LANG=C date`
	case ${__option} in
	-a)
		conv_date_fmt "${__time_now}" '%a %b %d %T %Z %Y' '%s'
		;;
	-e)
		eval '_time_'${__key}'_end'=`conv_date_fmt "${__time_now}" '%a %b %d %T %Z %Y' '%s'`
		;;
	-i)
		eval __time_start='${_time_'${__key}'_start}'
		eval __time_end='${_time_'${__key}'_end}'
		: $((__time_int = __time_end - __time_start))
		: $((__sec = __time_int % 60))
		: $((__min = __time_int / 60 % 60))
		: $((__hr  = __time_int / 60 / 60 % 60))
		printf "%02d:%02d:%02d\n" ${__hr} ${__min} ${__sec}
		;;
	-s)
		eval '_time_'${__key}'_start'=`conv_date_fmt "${__time_now}" '%a %b %d %T %Z %Y' '%s'`
		;;
	-S)
		case $2 in
		${dkgname})
			__time_log_file=${DAKEDIR}/+TIME
			;;
		*)
			__time_log_file=${DAKEDIR}/+TIME_`echo ${2}|tr '[:lower:]' '[:upper:]'`
			;;
		esac
		eval echo \"\${_time_${__key}_start} \${_time_${__key}_end} $((_time_${__key}_end - _time_${__key}_start))\" > ${__time_log_file}
		;;
	-T)
		__time_int=$2
		: $((__sec = __time_int % 60))
		: $((__min = __time_int / 60 % 60))
		: $((__hr  = __time_int / 60 / 60 % 60))
		printf "%02d:%02d:%02d\n" ${__hr} ${__min} ${__sec}
		;;
	*)
		conv_date_fmt "${__time_now}" '%a %b %d %T %Z %Y' '%Y.%m.%d %T'
		;;
	esac
}

doing()
{
    local __finish=false __time

    echo -n "$1"
    trap "__finish=true" 6
	__time=1
    while true; do
		if ${__finish}; then
			echo -n 'done'
			sleep 1
			break
		else
			echo -n '.'
			sleep 1
		fi
		: $((__time += 1))
		if [ $((__time % _log_rotate_interval)) -eq 0 ]; then
			logrotate
		fi
    done
    tput dl
    sleep 1
}

running()
{
	case $1 in
	start)
		shift
		doing "$1" &
		_doing_proc_id=$!
		;;
	stop)
		kill -6 ${_doing_proc_id}
		sleep 1
		;;
	esac
}

frotate()
{
	local __logfile __logfilename __logfiledir __logfiles __n

	__logfilename=`basename ${_logfile}`
	__logfiledir=`dirname ${_logfile}`
	__logfiles=`ls ${_logfile}.*${_logfile_sufx} 2> /dev/null | sort -r`
	if [ -z "${__logfiles}" ]; then
		__n=0
	else
		: $((__n = `echo "${__logfiles}" | wc -l`))
	fi
	if [ ${__n} -gt 0  -a  ${__n} -lt ${_log_rotate_count} ]; then
		for __logfile in ${__logfiles}; do
			mv ${__logfile} ${__logfiledir}/${__logfilename}.${__n}${_logfile_sufx}
			: $((__n -= 1))
		done
	elif [ ${__n} -eq ${_log_rotate_count} ]; then
		__logfiles=`poped __logfiles`
		for __logfile in ${__logfiles}; do
			: $((__n -= 1))
			mv ${__logfile} ${__logfiledir}/${__logfilename}.${__n}${_logfile_sufx}
		done
	elif [ ${__n} -gt ${_log_rotate_count} ]; then
		while [ ${__n}  -ge $((_log_rotate_count - 1)) ]; do
			rm -f `pop __logfiles`
			__logfiles=`poped __logfiles`
			: $((__n -= 1))
		done
		for __logfile in ${__logfiles}; do
			mv ${__logfile} ${__logfiledir}/${__logfilename}.${__n}${_logfile_sufx}
			: $((__n -= 1))
		done
	fi
}

get_loginfo()
{
	local __mode __flags

	while [ $# -gt 0 ] ; do
		case $1 in
		-s)
			__mode=suffix
			;;
		-c)
			__mode=ccommand
			;;
		*)
			break
			;;
		esac
		shift
	done
	__flags=$*
	case ${__mode} in
	suffix)
		case ${__flags} in
		*X*)
			echo '.xz'
			;;
		*J*)
			echo '.bz2'
			;;
		esac
		;;
	ccommand)
		case ${__flags} in
		*X*)
			echo 'xz -z'
			;;
		*J*)
			echo 'bzip2 -z'
			;;
		esac
		;;
	esac
}

logrotate()
{
    local __logfile __logtmpdir='/var/tmp' __logfilename __logfdir \
		__install_options="-m ${_logfile_mode}"

	__logfilename=`basename ${_logfile}`
	__logdir=`dirname ${_logfile}`
	if [ ! -f ${_logfile} ]; then
		touch ${_logfile}
		chmod ${_logfile_mode} ${_logfile}
		if [ -n "${_logfile_owner}" ]; then
			chown ${_logfile_owner} ${_logfile}
		fi
		(cd ${__logdir}; pax -r -w -l ${__logfilename} ${__logtmpdir})
	else
		if [ -n "${_logfile_owner}" ]; then
			__install_options="${__install_options} -o ${_logfile_owner%%:*} -g ${_logfile_owner##*:}"
		fi
		__logfilesize=`du -k ${_logfile} | awk '{print $1}'`
		if [ ${__logfilesize} -gt ${_log_rotate_size} ]; then
			install ${__install_options} ${__logtmpdir}/${__logfilename} ${_logfile}.0
			printf "%-20s%12s[%d]: logfile turned over due to size>%dK\n" "`putime`" \
				${dkgname} $$ ${_log_rotate_size} > ${__logtmpdir}/${__logfilename}
			frotate
			${_logcommpresscmd} ${_logfile}.0
		fi
	fi
}

dkgname='foo-1.0'

_log_rotate="\
# logfilename          [owner:group]    mode count size when  flags interval
/var/log/test.log                       644  7     10   \*     X     1"

set -- `echo "${_log_rotate}" | egrep -e '^/'`
case $# in
8)
	_logfile=$1
	_logfile_owner=$2
	_logfile_mode=$3
	: $((_log_rotate_count = $4))
	: $((_log_rotate_size = $5))
	_log_rotate_when=$6
	_logfile_sufx=`get_loginfo -s $7`
	_logcommpresscmd=`get_loginfo -c $7`
	: $((_log_rotate_interval = $8 * 60))
	;;
7)
	_logfile=$1
	_logfile_mode=$2
	: $((_log_rotate_count = $3))
	: $((_log_rotate_size = $4))
	_log_rotate_when=$5
	_logfile_sufx=`get_loginfo -s $6`
	_logcommpresscmd=`get_loginfo -c $6`
	: $((_log_rotate_interval = $7 * 60))
	;;
*)
	error initialize "wrong logrotate specifiation"
	;;
esac
echo $$ > /var/run/test.pid
trap "running stop; kill -9 $$" 2
logrotate
running start "Exec process"
exec >> /var/log/test.log 2>&1
cd /usr/src
make buildworld
