Merge "add cmd connection creation on creation ooh323 call data structure"
[asterisk/asterisk.git] / build_tools / download_externals
1 #!/usr/bin/env bash
2
3 if [[ ( ${BASH_VERSINFO[0]} == 4 && ${BASH_VERSINFO[1]} > 1 ) || ${BASH_VERSINFO[0]} > 4 ]] ; then
4         shopt -s compat41
5 fi
6 set -e
7
8
9 ASTTOPDIR=${ASTTOPDIR:-.}
10 export make=`sed -n -r -e "s/^MAKE\s*=\s*//gp" ${ASTTOPDIR}/makeopts`
11
12 getvar() {
13         $make --quiet --no-print-directory -f- <<EOF
14 include ${ASTTOPDIR}/makeopts
15 all:
16         @echo "\$($1)"
17 EOF
18 }
19
20 XMLSTARLET=`getvar XMLSTARLET`
21 ASTMODDIR=`getvar ASTMODDIR`
22 cache_dir=`getvar EXTERNALS_CACHE_DIR`
23 DOWNLOAD_TO_STDOUT=`getvar DOWNLOAD_TO_STDOUT`
24 HOST_CPU=`getvar HOST_CPU`
25 INSTALL=`getvar INSTALL`
26
27 module_name=${1%%-*}
28 variant=${1##*-}
29
30 if [[ "${variant}" = "${module_name}" ]] ; then
31         unset variant
32 fi
33
34 if [[ -z ${module_name} ]] ; then
35         echo "You must supply a module name."
36         exit 64
37 fi
38
39 tmpdir=$(mktemp -d)
40 if [[ -z "${tmpdir}" ]] ; then
41         echo "${module_name}: Unable to create temporary directory."
42         exit 1
43 fi
44 trap "rm -rf ${tmpdir}" EXIT
45
46 if [[ -z "${ASTMODDIR}" ]] ; then
47         echo "${module_name}: Unable to parse ${ASTTOPDIR}/makeopts."
48         exit 1
49 fi
50
51 if [[ "${XMLSTARLET}" = ":" ]] ; then
52         echo "${module_name}: The externals downloader requires xmlstarlet to be installed."
53         exit 1
54 fi
55
56 if [[ -z ${cache_dir} ]] ; then
57         cache_dir=${tmpdir}
58 fi
59
60 version=$(${ASTTOPDIR}/build_tools/make_version ${ASTTOPDIR})
61 if [[ ! ${version} =~ ^(GIT-)?(certified/)?([^.-]+)[.-].* ]] ; then
62         echo "${module_name}: Couldn't parse version ${version}"
63         exit 1
64 fi
65 major_version=${BASH_REMATCH[3]}
66
67 if [[ "${major_version}" == "master" ]] ; then
68         echo "${module_name}: External module downloading is not available in the 'master' git branch.  Please disable in menuselect and download manually."
69         exit 1
70 fi
71
72 major_version=${major_version}.0
73
74 if [[ "${HOST_CPU}" = "x86_64" ]] ; then
75         host_bits=64
76 else
77         host_bits=32
78 fi
79
80 if [[ -z "${variant}" ]] ; then
81         variants=$(${XMLSTARLET} sel -t -m "/menu/category/member[@name = '${module_name}']/member_data/downloader/variants/variant" -v "@tag" -n ${ASTTOPDIR}/menuselect-tree || :)
82         member_name=${module_name}
83         for tag in ${variants} ; do
84                 condition=$(${XMLSTARLET} sel -t -v "/menu/category/member[@name = '${module_name}']/member_data/downloader/variants/variant[@tag = '${tag}']/@condition" ${ASTTOPDIR}/menuselect-tree || :)
85                 variant=$(eval "if $condition ; then echo $tag ; fi")
86                 if [[ -n "${variant}" ]] ; then
87                         break
88                 fi
89         done
90 else
91         member_name=${module_name}${variant:+-${variant}}
92 fi
93
94 full_name=${module_name}${variant:+-${variant}}
95 variant_manifest=manifest${variant:+-${variant}}.xml
96
97 # Override the remote base for all packages
98 # useful for testing
99 remote_url=${REMOTE_BASE:+${REMOTE_BASE}/asterisk-${major_version}/x86-${host_bits}}
100
101 if [[ -z "${remote_url}" ]] ; then
102         remote_url=$(${XMLSTARLET} sel -t -v "/menu/category/member[@name = '${member_name}']/member_data/downloader/@remote_url" ${ASTTOPDIR}/menuselect-tree || :)
103         if [[ -n "${remote_url}" ]] ; then
104                 remote_url="${remote_url}/asterisk-${major_version}/x86-${host_bits}"
105         else
106                 directory_name=$(${XMLSTARLET} sel -t -v "/menu/category/member[@name = '${member_name}']/member_data/downloader/@directory_name" ${ASTTOPDIR}/menuselect-tree || :)
107                 remote_url="http://downloads.digium.com/pub/telephony/${directory_name:-${module_name}}/asterisk-${major_version}/x86-${host_bits}"
108         fi
109 fi
110
111 version_convert() {
112         local v=${1##*_}
113         if [[ ${v} =~ ([0-9]+)[.]([0-9]+)[.]([0-9]+) ]] ; then
114                 v=$(( ${BASH_REMATCH[1]}<<18 | ${BASH_REMATCH[2]}<<9 | ${BASH_REMATCH[3]} ))
115         fi
116         echo ${v}
117 }
118
119 ${DOWNLOAD_TO_STDOUT} ${remote_url}/${variant_manifest} > ${tmpdir}/${variant_manifest} || {
120         echo "${full_name}: Unable to fetch ${remote_url}/${variant_manifest}"
121         exit 1
122 }
123
124 rpv=$(${XMLSTARLET} sel -t -v "/package/@version" ${tmpdir}/${variant_manifest})
125 rpvi=$(version_convert ${rpv})
126 echo "${full_name}: Remote package version ${rpv} (${rpvi})"
127
128 module_dir=${full_name}-${rpv}-x86_${host_bits}
129 tarball=${module_dir}.tar.gz
130
131 export need_install=0
132
133 if [[ -f ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml ]] ; then
134         package_arch=$(${XMLSTARLET} sel -t -v "/package/@arch" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml)
135         ipv=$(${XMLSTARLET} sel -t -v "/package/@version" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml)
136         package_variant=$(${XMLSTARLET} sel -t -v "/package/@variant" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml || :)
137         ipvi=$(version_convert ${ipv})
138         ip_major=${ipv%_*}
139         echo "${full_name}: Installed package version ${ipv} (${ipvi})"
140         if [[ "${ip_major}" != "${major_version}" || "${package_arch}" != "x86_${host_bits}" || "${package_variant}" != "${variant}" ]] ; then
141                 echo "${full_name}: The installed package is not for this version of Asterisk.  Reinstalling."
142                 need_install=1
143         elif [[ ${rpvi} > ${ipvi} ]] ; then
144                 echo "${full_name}: A newer package is available"
145                 need_install=1
146         else
147                 sums=$(${XMLSTARLET} sel -t -m "//file" -v "@md5sum" -n ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml)
148                 for sum in ${sums} ; do
149                         install_path=$(${XMLSTARLET} sel -t -v "//file[@md5sum = '${sum}']/@install_path" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml )
150                         executable=$(${XMLSTARLET} sel -t -v "//file[@md5sum = '${sum}']/@executable" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml || : )
151                         f=${DESTDIR}$(eval echo ${install_path})
152                         if [[ ! -f ${f} ]] ; then
153                                 echo Not found: ${f}
154                                 need_install=1
155                                 break
156                         else
157                                 if [[ "$executable" = "yes" ]] ; then
158                                         # There are easier ways of doing this (objcopy --dump-section) but not in older bunutils
159                                         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")
160                                         tags=$($(eval 'printf "dd if=$f bs=1 count=%d skip=%d\n" $length_offset') 2>/dev/null)
161                                         if [[ -n "${tags}" && "${tags}" != "${module_name},${variant},${rpv}" ]] ; then
162                                                 echo Tag mismatch: ${f} File: "${tags}" Manifest: "${module_name},${variant},${rpv}"
163                                                 need_install=1
164                                                 break
165                                         fi
166                                 fi
167
168                                 cs=$(md5sum ${f} | cut -b1-32)
169                                 if [[ "${cs}" !=  "${sum}" ]] ; then
170                                         echo Checksum mismatch: ${f}
171                                         need_install=1
172                                         break
173                                 fi
174                         fi
175                 done
176         fi
177 else
178         need_install=1
179 fi
180
181 if [[ ${need_install} == 1 ]] ; then
182         if [[ ( -n "${ipvi}" ) && ${ipvi} > ${rpvi} ]] ; then
183                 echo "${full_name}: Installed package is newer than that available for download."
184                 exit 0
185         fi
186 else
187         echo "${full_name} is up to date."
188         exit 0;
189 fi
190
191 need_download=1
192 if [[ -f ${cache_dir}/${full_name}.manifest.xml ]] ; then
193         cpv=$(${XMLSTARLET} sel -t -v "/package/@version" ${cache_dir}/${full_name}.manifest.xml)
194         cpvi=$(version_convert ${cpv})
195         echo "${full_name}: Cached package version ${cpv} (${cpvi})"
196         if [[ ${cpvi} == ${rpvi} && ( -f ${cache_dir}/${tarball} ) ]] ; then
197                 echo "${full_name}: Cached version is available."
198                 need_download=0
199         fi
200 fi
201
202 if [[ ${need_download} = 1 ]] ; then
203         echo "${full_name}: Downloading ${remote_url}/${tarball} to ${cache_dir}/${tarball}"
204         ${DOWNLOAD_TO_STDOUT} ${remote_url}/${tarball} > ${cache_dir}/${tarball} || {
205                 echo "${full_name}: Unable to fetch ${remote_url}/${tarball}"
206                 exit 1
207         }
208         cp ${tmpdir}/${variant_manifest}  ${cache_dir}/${full_name}.manifest.xml
209 fi
210
211 tar -xzf ${cache_dir}/${tarball} -C ${cache_dir}
212 trap "rm -rf ${cache_dir}/${module_dir} ; rm -rf ${tmpdir}" EXIT
213
214 echo "${full_name}: Installing."
215
216 if [[ $EUID == 0 ]] ; then
217         install_params="--group=0 --owner=0"
218 fi
219
220 names=$(${XMLSTARLET} sel -t -m "//file" -v "@name" -n ${cache_dir}/${module_dir}/manifest.xml)
221 for name in ${names} ; do
222         source_path=${cache_dir}/${module_dir}/${name}
223         install_path=$(${XMLSTARLET} sel -t -v "//file[@name = '${name}']/@install_path" ${cache_dir}/${module_dir}/manifest.xml)
224         install_path=${DESTDIR}$(eval echo ${install_path})
225         executable=$(${XMLSTARLET} sel -t -v "//file[@name = '${name}']/@executable" ${cache_dir}/${module_dir}/manifest.xml || :)
226         if [[ "${executable}" = "yes" ]] ; then
227                 mode=0755
228         else
229                 mode=0644
230         fi
231
232         ${INSTALL} -Dp ${install_params} --mode=${mode} ${source_path} ${install_path}
233
234 done
235 ${INSTALL} -Dp ${install_params} --mode=0644 ${cache_dir}/${module_dir}/manifest.xml ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml
236
237 echo "${full_name}: Installed."