#!/bin/sh
#
# $Id$
#-------------------------------------------------------------------------------
# TeamFile サーバ用ダウンローダースクリプト
#
# Copyright (c) 2006,2007 COMPUTER HI-TECH INC., All rights reserved.
#-------------------------------------------------------------------------------
# [ 役割 ]
#    * TeamFile サーバの更新に必要なモジュールと更新用スクリプトを取得する
#    * 取得したスクリプトが破損していないことを保障する
#    * 取得したモジュールと更新用スクリプトのファイル一覧を提供する
#
#-------------------------------------------------------------------------------
# Usage: $0 [ -s ] サイレントモード
#           [ -d (ダウンロードモジュール格納ディレクトリ) ]
#           [ -f (ダウンロードモジュールの名称が記述されたファイル) ]
#           [ -e (更新用scriptファイルが記述されたファイル) ]
#           [ -h ] Usage 表示
#
#-------------------------------------------------------------------------------
# * "-f" で指定されるファイルへの出力フォーマット
# ------------------------------------------
#   (ファイル名)
#
# * "-e" で指定されるファイルへの出力フォーマット
# ------------------------------------------
#   (ファイル名)
#
# * $TF_MODULELIST_FILE のフォーマット
# ------------------------------------------
#   (パッケージ名),(MD5値),[s|p|f]
#
# * $TF_PROFILE_FILE のフォーマット
# ------------------------------------------
#	(キー) = (値)
#-------------------------------------------------------------------------------

#------------------
# set env
#------------------
if test -d "${TF_HOME}"; then
	MT_FUNCTION_HOME="${TF_HOME}/www/bin"
else
	MT_FUNCTION_HOME="/usr/local/teamfile/www/bin"
fi

MT_FUNCTION="${MT_FUNCTION_HOME}/mt-lib"
if test ! -f ${MT_FUNCTION}; then
	echo "The configuration script \"${MT_FUNCTION}\" was missing. Please check it."
	exit 1
fi

# read functions and configuration
. ${MT_FUNCTION}

GETTFMODULE="${TF_BINDIR}/gettfmodule.sh"

SILENT_MODE=0
DL_DIR_PATH="${TF_DOWNLOAD_PATH}"
DL_FILELIST_PATH="${TF_DOWNLOAD_PATH}/downloadlist"
DL_SCRIPTLIST_PATH="${TF_DOWNLOAD_PATH}/scriptlist"
DL_OLD_DOWNLOAD_PATH="${TF_DOWNLOAD_PATH}/old"

#---------------------------------------------------------------------
# Show Usage
#---------------------------------------------------------------------
usage() {
	echo "$0: [-s] [-d dirpath] [-f filepath] [-e] [-h]"
	echo "    -s : silent mode (no output screen)"
	echo "    -d : The directory path in which the downloaded modules are stored (default: ${TF_DOWNLOAD_PATH})"
	echo "    -f : The file path of downloaded module list (default: ${DL_FILELIST_PATH})"
	echo "    -e : The file path of downloaded script list (default: ${DL_SCRIPTLIST_PATH})"
	echo "    -h : show help"
}

#---------------------------------------------------------------------
# echo
#---------------------------------------------------------------------
ECHO() {
	if test "${SILENT_MODE}" = "0"; then
		echo "$@"
	fi

	echo `date`":  $@" >> ${TF_UPLOG_PATH}
}

#---------------------------------------------------------------------
# echo (no ouput date)
#---------------------------------------------------------------------
ECHO_NODATE() {
	if test "${SILENT_MODE}" = "0"; then
		echo "$@"
	fi

	echo "$@" >> ${TF_UPLOG_PATH}
}

#---------------------------------------------------------------------
# download file
# [ args ]
#     $1: filepath that you want to download
#     $2: The download uri
#---------------------------------------------------------------------
download_file() {

	dlfile="$1"
	dluri="$2"

	if test -z "${dlfile}" || test -z "${dluri}"; then
		return ${DL_ST_ERR}
	fi

	build_status_line "Download" "${dlfile}"
	if test "${SILENT_MODE}" = "0"; then
		$ECHO_N "${DL_STATUS_LINE} ... "$ECHO_C
	fi
	$ECHO_N `date`":  ${DL_STATUS_LINE} ... "$ECHO_C >> ${TF_UPLOG_PATH}

	PROXY_INFO=
	USESSL=
	if test "${TF_DL_USEPROXY}" = "on"; then
		PROXY_INFO=-b "${TF_DL_PROXYHOST}" -c "${TF_DL_PROXYPORT}" -d "${TF_DL_PROXYUSERID}" -e "${TF_DL_PROXYPASSWD}"
	fi
	if test "${TF_DL_USESSL}" = "on"; then
		USESSL="-S"
	fi

	$GETTFMODULE -U "${TF_DL_USERID}" -P "${TF_DL_PASSWD}" -h "${TF_DL_HOST}" -p "${TF_DL_PORT}" \
			-l "${dluri}" -O "${DL_DIR_PATH}/" -f "${dlfile}" ${PROXY_INFO} ${USESSL}
	RETVAL=$?
	case "$RETVAL" in
		0)
			ECHO_NODATE "ok"
			return ${DL_ST_FOUND_LIST}
			;;
		1)
			ECHO_NODATE "Invalid parameter found."
			return ${DL_ST_INVALID_PARAM}
			;;
		10)
			ECHO_NODATE "Auth failed."
			return ${DL_ST_ERR}
			;;
		11)
			ECHO_NODATE "Connection fialed."
			return ${DL_ST_ERR}
			;;
		12)
			ECHO_NODATE "Notfound"
			return ${DL_ST_NOTFOUND_FILE}
			;;
		13)
			ECHO_NODATE "Failed to get file."
			return ${DL_ST_NOTFOUND_FILE}
			;;
		20)
			ECHO_NODATE "Download directory missing."
			return ${DL_ST_ERR}
			;;
		21)
			ECHO_NODATE "Failed to write downloaded file"
			return ${DL_ST_ERR}
			;;
		22)
			ECHO_NODATE "Download failed"
			return ${DL_ST_ERR}
			;;
		99)
			ECHO_NODATE "Unknown error"
			return ${DL_ST_ERR}
			;;
	esac
	return ${RETVAL}
}


#---------------------------------------------------------------------
# main
#---------------------------------------------------------------------
while getopts sd:f:e:h OPT
do
	case $OPT in
		s)
			SILENT_MODE=1
			;;
		d)
			DL_DIR_PATH="$OPTARG"
			;;
		f)
			DL_FILELIST_PATH="$OPTARG"
			;;
		e)
			DL_SCRIPTLIST_PATH="$OPTARG"
			;;
		h)
			usage
			exit ${DL_ST_MISSING_PARAM}
			;;
		\?)
			usage
			exit ${DL_ST_MISSING_PARAM}
			;;
	esac
done
shift `expr $OPTIND - 1`

#--------------------------
# (1) check parameters
#--------------------------
# check download path
if test ! -d "${DL_DIR_PATH}"; then
	ECHO "The path of downloaded modules was not valid directory."
	exit ${DL_ST_MISSING_PARAM}
fi

# check $GETTFMODULE
if test ! -x "$GETTFMODULE"; then
	ECHO "$GETTFMODULE is missing or not is executable."
	exit ${DL_ST_ERR}
fi

# check parameters for $GETTFMODULE
if test -z "${TF_DL_USERID}" || test -z "${TF_DL_PASSWD}" || \
   test -z "${TF_DL_HOST}"   || test -z "${TF_DL_PORT}"   || \
   test -z "${TF_DL_LOCATION}"; then
	ECHO "Some parameters for $GETTFMODULE are missing. "
	ECHO "Please check \"tfenvvars\"."
	exit ${DL_ST_MISSING_PARAM}
fi

#---------------------------------------------------------------------
# (2) backup old modules ($TF_DOWNLOAD_PATH -> $DL_OLD_DOWNLOAD_PATH) 
#     and setup files
#---------------------------------------------------------------------
if test ! -d ${DL_OLD_DOWNLOAD_PATH}; then
	mkdir -p ${DL_OLD_DOWNLOAD_PATH}
fi

BACKUP_LIST=`find ${DL_DIR_PATH} -maxdepth 1 -type f -print`
for f in ${BACKUP_LIST};
do
	mv $f ${DL_OLD_DOWNLOAD_PATH}/
done

# create empty files
touch ${DL_FILELIST_PATH} ${DL_SCRIPTLIST_PATH} ${TF_UPLOG_PATH}

#---------------------------------------------------------------------
# Download modules
#---------------------------------------------------------------------
# replace @xxx@ parameters
getOsType
TYPE_RELEASE=${OS_RELEASE_STR}
TYPE_OS=`uname -s`
TYPE_PLATFORM=`uname -i`
TYPE_ARCH=`uname -p`

get_package_version_string
TF_VERSION=`echo $PKG_VERSION_STR | sed 's/\.[a-z]*[0-9]$//g'`
DL_URI_LIST=`echo ${TF_DL_LOCATION} | sed -e 's:@os@:'"${TYPE_OS}"':g' -e 's:@platform@:'"${TYPE_PLATFORM}"':g' -e 's:@arch@:'"${TYPE_ARCH}"':g' -e 's:@release@:'"${TYPE_RELEASE}"':g' -e 's:@tfversion@:'"${TF_VERSION}"':g'`

# download files
for uri in ${DL_URI_LIST};
do
	# %20 -> half space and
	# replace dobule slash and append slash
	location=`echo /$uri | sed -e 's/%20/ /g' -e 's:[/]\{2,\}:/:g' -e '1s:[^/]$:&/:'`

	ECHO "* [ download uri : ${location} ]"

	#-------------------------------------
	# (3) download $TF_MODULELIST_FILE
	#-------------------------------------
	download_file "${TF_MODULELIST_FILE}" "${location}"
	RETVAL=$?
	if test "${RETVAL}" = "${DL_ST_NOTFOUND_FILE}"; then
		continue
	elif test "${RETVAL}" != "${DL_ST_FOUND_LIST}"; then
		exit ${RETVAL}
	fi

	#-------------------------------------
	# (4) download $TF_PROFILE_FILE
	#-------------------------------------
	download_file "${TF_PROFILE_FILE}" "${location}"
	RETVAL=$?
	if test "${RETVAL}" != "${DL_ST_NOTFOUND_FILE}" && \
	   test "${RETVAL}" != "${DL_ST_FOUND_LIST}"; then
		exit ${RETVAL}
	fi

	#-------------------------------------
	# (5) download files and check digest
	#-------------------------------------
	PKGS=`cat ${DL_DIR_PATH}/${TF_MODULELIST_FILE} | sed -e '/^#/d' | cut -d, -s -f1`
	for f in ${PKGS};
	do
		pkg="${DL_DIR_PATH}/$f"
		old_pkg="${DL_OLD_DOWNLOAD_PATH}/$f"
		target_line=`cat ${DL_DIR_PATH}/${TF_MODULELIST_FILE} | sed -e '/^#/d' | sed -n -e  "/$f/p"`
		listed_md5=`echo ${target_line} | cut -d, -s -f2`
		listed_flag=`echo ${target_line} | cut -d, -s -f3`

		# The file that downloaded from another location found
		if test -f ${pkg}; then
			get_md5 ${pkg}
			if test "${MD5_DIGEST}" != "${listed_md5}"; then
				download_file "$f" "${location}"
				RETVAL=$?
				if test "${RETVAL}" != "${DL_ST_FOUND_LIST}"; then
					exit ${RETVAL}
				fi
			else
				build_status_line "Download" "$f"
				ECHO "${DL_STATUS_LINE} ... same"
				continue
			fi
		# The old file found
		elif test -f ${old_pkg}; then
			get_md5 ${old_pkg}
			if test "${MD5_DIGEST}" != "${listed_md5}"; then
				download_file "$f" "${location}"
				RETVAL=$?
				if test "${RETVAL}" != "${DL_ST_FOUND_LIST}"; then
					exit ${RETVAL}
				fi
			else
				mv ${old_pkg} ${DL_DIR_PATH}/
				build_status_line "Download" "$f"
				ECHO "${DL_STATUS_LINE} ... already downloaded"

				if test "${listed_flag}" = "s"; then
					echo "$f" >> ${DL_SCRIPTLIST_PATH}
				elif test "${listed_flag}" = "p"; then
					echo "$f" >> ${DL_FILELIST_PATH}
				fi
				continue
			fi
		# The new or old file not found
		else
			download_file "$f" "${location}"
			RETVAL=$?
			if test "${RETVAL}" != "${DL_ST_FOUND_LIST}"; then
				exit ${RETVAL}
			fi
		fi

		# check digest
		get_md5 ${pkg}
		if test "${MD5_DIGEST}" != "${listed_md5}"; then
			ECHO "Missmatch MD5 (file = $f, md5 = ${MD5_DIGEST}, listed md5 = ${listed_md5})"
			exit ${DL_ST_MISSMATCH_HASH}
		fi

		# write filename
		if test "${listed_flag}" = "s"; then
			echo "$f" >> ${DL_SCRIPTLIST_PATH}
		elif test "${listed_flag}" = "p"; then
			echo "$f" >> ${DL_FILELIST_PATH}
		fi
	done
done

# check downloaded filelist
if test -s ${DL_FILELIST_PATH} || test -s ${DL_SCRIPTLIST_PATH}; then
	exit ${DL_ST_FOUND_LIST}
fi

exit ${DL_ST_NOTFOUND_LIST}

