123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- #!/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:-.}
- export make=`sed -n -r -e "s/^MAKE\s*=\s*//gp" ${ASTTOPDIR}/makeopts`
- getvar() {
- $make --quiet --no-print-directory -f- <<EOF
- include ${ASTTOPDIR}/makeopts
- all:
- @echo "\$($1)"
- EOF
- }
- XMLSTARLET=`getvar XMLSTARLET`
- ASTMODDIR=`getvar ASTMODDIR`
- cache_dir=`getvar EXTERNALS_CACHE_DIR`
- DOWNLOAD_TO_STDOUT=`getvar DOWNLOAD_TO_STDOUT`
- HOST_CPU=`getvar HOST_CPU`
- INSTALL=`getvar INSTALL`
- 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
- if [[ -z "${ASTMODDIR}" ]] ; then
- echo "${module_name}: Unable to parse ${ASTTOPDIR}/makeopts."
- exit 1
- fi
- if [[ "${XMLSTARLET}" = ":" ]] ; then
- echo "${module_name}: The externals downloader requires xmlstarlet to be installed."
- exit 1
- fi
- if [[ -z ${cache_dir} ]] ; then
- cache_dir=${tmpdir}
- fi
- version=$(${ASTTOPDIR}/build_tools/make_version ${ASTTOPDIR})
- if [[ ! ${version} =~ ^(GIT-)?(certified/)?([^.-]+)[.-].* ]] ; then
- echo "${module_name}: Couldn't parse version ${version}"
- exit 1
- fi
- major_version=${BASH_REMATCH[3]}
- 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}
- }
- ${DOWNLOAD_TO_STDOUT} ${remote_url}/${variant_manifest} > ${tmpdir}/${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=$(${MD5} ${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} to ${cache_dir}/${tarball}"
- ${DOWNLOAD_TO_STDOUT} ${remote_url}/${tarball} > ${cache_dir}/${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="-g 0 -o 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} -m ${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."
|