
This was broken in commit882e707e40
, which changed 'plain()' messages to go to stdout, which was then captured as the download client in question: cmdline=("Aborting..."). The result was a very confusing error message e.g. /usr/share/makepkg/source/file.sh: line 72: $'\E[1m': command not found or with makepkg --nocolor: /usr/share/makepkg/source/file.sh: line 72: Aborting...: command not found The problem here is that we checked to see if an asynchronous subshell, in our case <(...), failed, by checking if its captured stdout is non-empty. Which is terrible, and also a limitation of old bash. But bash 4.4 can use wait $! to retrieve the return value of an asynchronous subshell. Now we target that as our minimum, we can sanely handle errors in such functions. Losing error messages on stdout by capturing them in a variable instead of printing them, continues to be a problem, but this will be fixed systematically in a later commit. Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> Signed-off-by: Allan McRae <allan@archlinux.org> (cherry picked from commit381e113755
)
148 lines
3.8 KiB
Bash
148 lines
3.8 KiB
Bash
#!/bin/bash
|
|
#
|
|
# file.sh - function for handling the download and extraction of source files
|
|
#
|
|
# Copyright (c) 2015-2020 Pacman Development Team <pacman-dev@archlinux.org>
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
[[ -n "$LIBMAKEPKG_SOURCE_FILE_SH" ]] && return
|
|
LIBMAKEPKG_SOURCE_FILE_SH=1
|
|
|
|
|
|
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
|
|
|
|
source "$LIBRARY/util/message.sh"
|
|
source "$LIBRARY/util/pkgbuild.sh"
|
|
|
|
|
|
download_file() {
|
|
local netfile=$1
|
|
|
|
local filepath=$(get_filepath "$netfile")
|
|
if [[ -n "$filepath" ]]; then
|
|
msg2 "$(gettext "Found %s")" "${filepath##*/}"
|
|
return
|
|
fi
|
|
|
|
local proto=$(get_protocol "$netfile")
|
|
|
|
# find the client we should use for this URL
|
|
local -a cmdline
|
|
IFS=' ' read -a cmdline < <(get_downloadclient "$proto")
|
|
wait $! || exit
|
|
|
|
local filename=$(get_filename "$netfile")
|
|
local url=$(get_url "$netfile")
|
|
|
|
if [[ $proto = "scp" ]]; then
|
|
# scp downloads should not pass the protocol in the url
|
|
url="${url##*://}"
|
|
fi
|
|
|
|
msg2 "$(gettext "Downloading %s...")" "$filename"
|
|
|
|
# temporary download file, default to last component of the URL
|
|
local dlfile="${url##*/}"
|
|
|
|
# replace %o by the temporary dlfile if it exists
|
|
if [[ ${cmdline[*]} = *%o* ]]; then
|
|
dlfile=$filename.part
|
|
cmdline=("${cmdline[@]//%o/$dlfile}")
|
|
fi
|
|
# add the URL, either in place of %u or at the end
|
|
if [[ ${cmdline[*]} = *%u* ]]; then
|
|
cmdline=("${cmdline[@]//%u/$url}")
|
|
else
|
|
cmdline+=("$url")
|
|
fi
|
|
|
|
if ! command -- "${cmdline[@]}" >&2; then
|
|
[[ ! -s $dlfile ]] && rm -f -- "$dlfile"
|
|
error "$(gettext "Failure while downloading %s")" "$url"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
fi
|
|
|
|
# rename the temporary download file to the final destination
|
|
if [[ $dlfile != "$filename" ]]; then
|
|
mv -f "$SRCDEST/$dlfile" "$SRCDEST/$filename"
|
|
fi
|
|
}
|
|
|
|
extract_file() {
|
|
local netfile=$1
|
|
|
|
local file=$(get_filename "$netfile")
|
|
local filepath=$(get_filepath "$file")
|
|
rm -f "$srcdir/${file}"
|
|
ln -s "$filepath" "$srcdir/"
|
|
|
|
if in_array "$file" "${noextract[@]}"; then
|
|
# skip source files in the noextract=() array
|
|
# these are marked explicitly to NOT be extracted
|
|
return 0
|
|
fi
|
|
|
|
# do not rely on extension for file type
|
|
local file_type=$(@FILECMD@ -bizL -- "$file")
|
|
local ext=${file##*.}
|
|
local cmd=''
|
|
case "$file_type" in
|
|
*application/x-tar*|*application/zip*|*application/x-zip*|*application/x-cpio*)
|
|
cmd="bsdtar" ;;
|
|
*application/x-gzip*|*application/gzip*)
|
|
case "$ext" in
|
|
gz|z|Z) cmd="gzip" ;;
|
|
*) return;;
|
|
esac ;;
|
|
*application/x-bzip*)
|
|
case "$ext" in
|
|
bz2|bz) cmd="bzip2" ;;
|
|
*) return;;
|
|
esac ;;
|
|
*application/x-xz*)
|
|
case "$ext" in
|
|
xz) cmd="xz" ;;
|
|
*) return;;
|
|
esac ;;
|
|
*)
|
|
# See if bsdtar can recognize the file
|
|
if bsdtar -tf "$file" -q '*' &>/dev/null; then
|
|
cmd="bsdtar"
|
|
else
|
|
return 0
|
|
fi ;;
|
|
esac
|
|
|
|
local ret=0
|
|
msg2 "$(gettext "Extracting %s with %s")" "$file" "$cmd"
|
|
if [[ $cmd = "bsdtar" ]]; then
|
|
$cmd -xf "$file" || ret=$?
|
|
else
|
|
rm -f -- "${file%.*}"
|
|
$cmd -dcf -- "$file" > "${file%.*}" || ret=$?
|
|
fi
|
|
if (( ret )); then
|
|
error "$(gettext "Failed to extract %s")" "$file"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
fi
|
|
|
|
if (( EUID == 0 )); then
|
|
# change perms of all source files to root user & root group
|
|
chown -R 0:0 "$srcdir"
|
|
fi
|
|
}
|