mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-11-03 04:16:43 +00:00 
			
		
		
		
	Needed to ignore an xmlstarlet return code for optional element. Change-Id: I6a96f709b4b38c9a3f3dda4e8b07903787e16873 Reported-by: Dan Jenkins
		
			
				
	
	
		
			225 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			225 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env bash
 | 
						|
 | 
						|
if [[ ( ${BASH_VERSINFO[0]} == 4 && ${BASH_VERSINFO[1]} > 1 ) || ${BASH_VERSINFO[0]} > 4 ]] ; then
 | 
						|
	shopt -s compat41
 | 
						|
fi
 | 
						|
set -e
 | 
						|
 | 
						|
ASTTOPDIR=${ASTTOPDIR:-.}
 | 
						|
 | 
						|
module_name=${1%%-*}
 | 
						|
variant=${1##*-}
 | 
						|
 | 
						|
if [[ "${variant}" = "${module_name}" ]] ; then
 | 
						|
	unset variant
 | 
						|
fi
 | 
						|
 | 
						|
if [[ -z ${module_name} ]] ; then
 | 
						|
	echo "You must supply a module name."
 | 
						|
	exit 64
 | 
						|
fi
 | 
						|
 | 
						|
tmpdir=$(mktemp -d)
 | 
						|
if [[ -z "${tmpdir}" ]] ; then
 | 
						|
	echo "${module_name}: Unable to create temporary directory."
 | 
						|
	exit 1
 | 
						|
fi
 | 
						|
trap "rm -rf ${tmpdir}" EXIT
 | 
						|
 | 
						|
sed -r -e "s/^([^ =]+)\s*=\s*(.*)$/\1=\"\2\"/g" ${ASTTOPDIR}/makeopts >${tmpdir}/makeopts
 | 
						|
source ${tmpdir}/makeopts
 | 
						|
if [[ -z "${ASTMODDIR}" ]] ; then
 | 
						|
	echo "${module_name}: Unable to parse ${ASTTOPDIR}/makeopts."
 | 
						|
	exit 1
 | 
						|
fi
 | 
						|
 | 
						|
XMLSTARLET=${XMLSTARLET:-xmlstarlet}
 | 
						|
if [[ "${XMLSTARLET}" = ":" ]] ; then
 | 
						|
	echo "${module_name}: The externals downloader requires xmlstarlet to be installed."
 | 
						|
	exit 1
 | 
						|
fi
 | 
						|
 | 
						|
cache_dir="${EXTERNALS_CACHE_DIR}"
 | 
						|
if [[ -z ${cache_dir} ]] ; then
 | 
						|
	cache_dir=${tmpdir}
 | 
						|
fi
 | 
						|
 | 
						|
version=$(${ASTTOPDIR}/build_tools/make_version ${ASTTOPDIR})
 | 
						|
if [[ ! ${version} =~ ^(GIT-)?([^.-]+)[.-].* ]] ; then
 | 
						|
	echo "${module_name}: Couldn't parse version ${version}"
 | 
						|
	exit 1
 | 
						|
fi
 | 
						|
major_version=${BASH_REMATCH[2]}
 | 
						|
 | 
						|
if [[ "${major_version}" == "master" ]] ; then
 | 
						|
	echo "${module_name}: External module downloading is not available in the 'master' git branch.  Please disable in menuselect and download manually."
 | 
						|
	exit 1
 | 
						|
fi
 | 
						|
 | 
						|
major_version=${major_version}.0
 | 
						|
 | 
						|
if [[ "${HOST_CPU}" = "x86_64" ]] ; then
 | 
						|
	host_bits=64
 | 
						|
else
 | 
						|
	host_bits=32
 | 
						|
fi
 | 
						|
 | 
						|
if [[ -z "${variant}" ]] ; then
 | 
						|
	variants=$(${XMLSTARLET} sel -t -m "/menu/category/member[@name = '${module_name}']/member_data/downloader/variants/variant" -v "@tag" -n ${ASTTOPDIR}/menuselect-tree || :)
 | 
						|
	member_name=${module_name}
 | 
						|
	for tag in ${variants} ; do
 | 
						|
		condition=$(${XMLSTARLET} sel -t -v "/menu/category/member[@name = '${module_name}']/member_data/downloader/variants/variant[@tag = '${tag}']/@condition" ${ASTTOPDIR}/menuselect-tree || :)
 | 
						|
		variant=$(eval "if $condition ; then echo $tag ; fi")
 | 
						|
		if [[ -n "${variant}" ]] ; then
 | 
						|
			break
 | 
						|
		fi
 | 
						|
	done
 | 
						|
else
 | 
						|
	member_name=${module_name}${variant:+-${variant}}
 | 
						|
fi
 | 
						|
 | 
						|
full_name=${module_name}${variant:+-${variant}}
 | 
						|
variant_manifest=manifest${variant:+-${variant}}.xml
 | 
						|
 | 
						|
# Override the remote base for all packages
 | 
						|
# useful for testing
 | 
						|
remote_url=${REMOTE_BASE:+${REMOTE_BASE}/asterisk-${major_version}/x86-${host_bits}}
 | 
						|
 | 
						|
if [[ -z "${remote_url}" ]] ; then
 | 
						|
	remote_url=$(${XMLSTARLET} sel -t -v "/menu/category/member[@name = '${member_name}']/member_data/downloader/@remote_url" ${ASTTOPDIR}/menuselect-tree || :)
 | 
						|
	if [[ -n "${remote_url}" ]] ; then
 | 
						|
		remote_url="${remote_url}/asterisk-${major_version}/x86-${host_bits}"
 | 
						|
	else
 | 
						|
		directory_name=$(${XMLSTARLET} sel -t -v "/menu/category/member[@name = '${member_name}']/member_data/downloader/@directory_name" ${ASTTOPDIR}/menuselect-tree || :)
 | 
						|
		remote_url="http://downloads.digium.com/pub/telephony/${directory_name:-${module_name}}/asterisk-${major_version}/x86-${host_bits}"
 | 
						|
	fi
 | 
						|
fi
 | 
						|
 | 
						|
version_convert() {
 | 
						|
	local v=${1##*_}
 | 
						|
	if [[ ${v} =~ ([0-9]+)[.]([0-9]+)[.]([0-9]+) ]] ; then
 | 
						|
		v=$(( ${BASH_REMATCH[1]}<<18 | ${BASH_REMATCH[2]}<<9 | ${BASH_REMATCH[3]} ))
 | 
						|
	fi
 | 
						|
	echo ${v}
 | 
						|
}
 | 
						|
 | 
						|
${WGET} -q -O ${tmpdir}/${variant_manifest} ${remote_url}/${variant_manifest} || {
 | 
						|
	echo "${full_name}: Unable to fetch ${remote_url}/${variant_manifest}"
 | 
						|
	exit 1
 | 
						|
}
 | 
						|
 | 
						|
rpv=$(${XMLSTARLET} sel -t -v "/package/@version" ${tmpdir}/${variant_manifest})
 | 
						|
rpvi=$(version_convert ${rpv})
 | 
						|
echo "${full_name}: Remote package version ${rpv} (${rpvi})"
 | 
						|
 | 
						|
module_dir=${full_name}-${rpv}-x86_${host_bits}
 | 
						|
tarball=${module_dir}.tar.gz
 | 
						|
 | 
						|
export need_install=0
 | 
						|
 | 
						|
if [[ -f ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml ]] ; then
 | 
						|
	package_arch=$(${XMLSTARLET} sel -t -v "/package/@arch" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml)
 | 
						|
	ipv=$(${XMLSTARLET} sel -t -v "/package/@version" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml)
 | 
						|
	package_variant=$(${XMLSTARLET} sel -t -v "/package/@variant" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml || :)
 | 
						|
	ipvi=$(version_convert ${ipv})
 | 
						|
	ip_major=${ipv%_*}
 | 
						|
	echo "${full_name}: Installed package version ${ipv} (${ipvi})"
 | 
						|
	if [[ "${ip_major}" != "${major_version}" || "${package_arch}" != "x86_${host_bits}" || "${package_variant}" != "${variant}" ]] ; then
 | 
						|
		echo "${full_name}: The installed package is not for this version of Asterisk.  Reinstalling."
 | 
						|
		need_install=1
 | 
						|
	elif [[ ${rpvi} > ${ipvi} ]] ; then
 | 
						|
		echo "${full_name}: A newer package is available"
 | 
						|
		need_install=1
 | 
						|
	else
 | 
						|
		sums=$(${XMLSTARLET} sel -t -m "//file" -v "@md5sum" -n ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml)
 | 
						|
		for sum in ${sums} ; do
 | 
						|
			install_path=$(${XMLSTARLET} sel -t -v "//file[@md5sum = '${sum}']/@install_path" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml )
 | 
						|
			executable=$(${XMLSTARLET} sel -t -v "//file[@md5sum = '${sum}']/@executable" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml || : )
 | 
						|
			f=${DESTDIR}$(eval echo ${install_path})
 | 
						|
			if [[ ! -f ${f} ]] ; then
 | 
						|
				echo Not found: ${f}
 | 
						|
				need_install=1
 | 
						|
				break
 | 
						|
			else
 | 
						|
				if [[ "$executable" = "yes" ]] ; then
 | 
						|
					# There are easier ways of doing this (objcopy --dump-section) but not in older bunutils
 | 
						|
					length_offset=$(objdump -h $f | sed -n -r -e "s/^\s+[0-9]+\s+.ast_manifest\s+([0-9a-fA-F]+)\s+[0-9a-fA-F]+\s+[0-9a-fA-F]+\s+([0-9a-fA-F]+)\s+.*$/0x\1 0x\2/p")
 | 
						|
					tags=$($(eval 'printf "dd if=$f bs=1 count=%d skip=%d\n" $length_offset') 2>/dev/null)
 | 
						|
					if [[ -n "${tags}" && "${tags}" != "${module_name},${variant},${rpv}" ]] ; then
 | 
						|
						echo Tag mismatch: ${f} File: "${tags}" Manifest: "${module_name},${variant},${rpv}"
 | 
						|
						need_install=1
 | 
						|
						break
 | 
						|
					fi
 | 
						|
				fi
 | 
						|
 | 
						|
				cs=$(md5sum ${f} | cut -b1-32)
 | 
						|
				if [[ "${cs}" !=  "${sum}" ]] ; then
 | 
						|
					echo Checksum mismatch: ${f}
 | 
						|
					need_install=1
 | 
						|
					break
 | 
						|
				fi
 | 
						|
			fi
 | 
						|
		done
 | 
						|
	fi
 | 
						|
else
 | 
						|
	need_install=1
 | 
						|
fi
 | 
						|
 | 
						|
if [[ ${need_install} == 1 ]] ; then
 | 
						|
	if [[ ( -n "${ipvi}" ) && ${ipvi} > ${rpvi} ]] ; then
 | 
						|
		echo "${full_name}: Installed package is newer than that available for download."
 | 
						|
		exit 0
 | 
						|
	fi
 | 
						|
else
 | 
						|
	echo "${full_name} is up to date."
 | 
						|
	exit 0;
 | 
						|
fi
 | 
						|
 | 
						|
need_download=1
 | 
						|
if [[ -f ${cache_dir}/${full_name}.manifest.xml ]] ; then
 | 
						|
	cpv=$(${XMLSTARLET} sel -t -v "/package/@version" ${cache_dir}/${full_name}.manifest.xml)
 | 
						|
	cpvi=$(version_convert ${cpv})
 | 
						|
	echo "${full_name}: Cached package version ${cpv} (${cpvi})"
 | 
						|
	if [[ ${cpvi} == ${rpvi} && ( -f ${cache_dir}/${tarball} ) ]] ; then
 | 
						|
		echo "${full_name}: Cached version is available."
 | 
						|
		need_download=0
 | 
						|
	fi
 | 
						|
fi
 | 
						|
 | 
						|
if [[ ${need_download} = 1 ]] ; then
 | 
						|
	echo "${full_name}: Downloading ${remote_url}/${tarball}"
 | 
						|
	${WGET} -q -O ${cache_dir}/${tarball} ${remote_url}/${tarball} || {
 | 
						|
		echo "${full_name}: Unable to fetch ${remote_url}/${tarball}"
 | 
						|
		exit 1
 | 
						|
	}
 | 
						|
	cp ${tmpdir}/${variant_manifest}  ${cache_dir}/${full_name}.manifest.xml
 | 
						|
fi
 | 
						|
 | 
						|
tar -xzf ${cache_dir}/${tarball} -C ${cache_dir}
 | 
						|
trap "rm -rf ${cache_dir}/${module_dir} ; rm -rf ${tmpdir}" EXIT
 | 
						|
 | 
						|
echo "${full_name}: Installing."
 | 
						|
 | 
						|
if [[ $EUID == 0 ]] ; then
 | 
						|
	install_params="--group=0 --owner=0"
 | 
						|
fi
 | 
						|
 | 
						|
names=$(${XMLSTARLET} sel -t -m "//file" -v "@name" -n ${cache_dir}/${module_dir}/manifest.xml)
 | 
						|
for name in ${names} ; do
 | 
						|
	source_path=${cache_dir}/${module_dir}/${name}
 | 
						|
	install_path=$(${XMLSTARLET} sel -t -v "//file[@name = '${name}']/@install_path" ${cache_dir}/${module_dir}/manifest.xml)
 | 
						|
	install_path=${DESTDIR}$(eval echo ${install_path})
 | 
						|
	executable=$(${XMLSTARLET} sel -t -v "//file[@name = '${name}']/@executable" ${cache_dir}/${module_dir}/manifest.xml || :)
 | 
						|
	if [[ "${executable}" = "yes" ]] ; then
 | 
						|
		mode=0755
 | 
						|
	else
 | 
						|
		mode=0644
 | 
						|
	fi
 | 
						|
 | 
						|
	${INSTALL} -Dp ${install_params} --mode=${mode} ${source_path} ${install_path}
 | 
						|
 | 
						|
done
 | 
						|
${INSTALL} -Dp ${install_params} --mode=0644 ${cache_dir}/${module_dir}/manifest.xml ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml
 | 
						|
 | 
						|
echo "${full_name}: Installed."
 |