mirror of
				https://gitee.com/spark-store-project/spark-store
				synced 2025-11-04 16:22:19 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			688 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			688 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/bash
 | 
						||
#	
 | 
						||
# apt-fast v1.9
 | 
						||
# Use this just like aptitude or apt-get for faster package downloading.
 | 
						||
#
 | 
						||
# Copyright: 2008-2012 Matt Parnell, http://www.mattparnell.com
 | 
						||
# Improvements, maintenance, revisions - 2012, 2017-2018 Dominique Lasserre
 | 
						||
#
 | 
						||
# You may distribute this file under the terms of the GNU General
 | 
						||
# Public License as published by the Free Software Foundation; either
 | 
						||
# version 3 of the License, or (at your option) any later version.
 | 
						||
#
 | 
						||
[ -n "$DEBUG" ] && set -xv
 | 
						||
 | 
						||
# Print colored messages.
 | 
						||
# Usage: msg "message text" "message type" "optional: err"
 | 
						||
# Message types are 'normal', 'hint' or 'warning'. Warnings and messages with a
 | 
						||
# third argument are piped to stderr.
 | 
						||
msg(){
 | 
						||
  msg_options=()
 | 
						||
  case "$2" in
 | 
						||
    normal) beginColor="$cGreen";;
 | 
						||
    hint) beginColor="$cBlue";;
 | 
						||
    warning) beginColor="$cRed";;
 | 
						||
    question) beginColor="$cRed"; msg_options=(-n);;
 | 
						||
    *) beginColor= ;;
 | 
						||
  esac
 | 
						||
 | 
						||
  if [ -z "$3" ] && [ "$2" != "warning" ]; then
 | 
						||
    echo -e "${msg_options[@]}" "${aptfast_prefix}${beginColor}$1${endColor}"
 | 
						||
  else
 | 
						||
    echo -e "${msg_options[@]}" "${aptfast_prefix}${beginColor}$1${endColor}" >&2
 | 
						||
  fi
 | 
						||
}
 | 
						||
 | 
						||
# Search for known options and decide if root privileges are needed.
 | 
						||
root=1  # default value: we need root privileges
 | 
						||
option=
 | 
						||
for argument in "$@"; do
 | 
						||
  case "$argument" in
 | 
						||
    upgrade | full-upgrade | install | dist-upgrade | build-dep)
 | 
						||
      option="install"
 | 
						||
      ;;
 | 
						||
    clean | autoclean)
 | 
						||
      option="clean"
 | 
						||
      ;;
 | 
						||
    download)
 | 
						||
      option="download"
 | 
						||
      root=0
 | 
						||
      ;;
 | 
						||
    source)
 | 
						||
      option="source"
 | 
						||
      root=0
 | 
						||
      ;;
 | 
						||
    changelog|search|policy|show)
 | 
						||
      root=0
 | 
						||
      ;;
 | 
						||
  esac
 | 
						||
done
 | 
						||
 | 
						||
# To handle priority of options correctly (environment over config file vars)
 | 
						||
# we need to preserve all interesting env variables. As this wouldn't be
 | 
						||
# difficult enough we have to preserve complete env vars (especially if value
 | 
						||
# ist set (even empty) or not) when changing context (sudo)...
 | 
						||
# Set a 'random' string to all unset variables.
 | 
						||
TMP_RANDOM="13979853562951413"
 | 
						||
TMP_LCK_FILE="${LCK_FILE-${TMP_RANDOM}}"
 | 
						||
TMP_DOWNLOADBEFORE="${DOWNLOADBEFORE-${TMP_RANDOM}}"
 | 
						||
TMP__APTMGR="${_APTMGR-${TMP_RANDOM}}"
 | 
						||
TMP_APTCACHE="${APTCACHE-${TMP_RANDOM}}"
 | 
						||
TMP_DLDIR="${DLDIR-${TMP_RANDOM}}"
 | 
						||
TMP_DLLIST="${DLLIST-${TMP_RANDOM}}"
 | 
						||
TMP_LISTDIR="${LISTDIR-${TMP_RANDOM}}"
 | 
						||
TMP__MAXNUM="${MAXNUM-${TMP_RANDOM}}"
 | 
						||
TMP__MAXCONPERSRV="${MAXCONPERSRV-${TMP_RANDOM}}"
 | 
						||
TMP__SPLITCON="${SPLITCON-${TMP_RANDOM}}"
 | 
						||
TMP__MINSPLITSZ=${MINSPLITSZ-${TMP_RANDOM}}
 | 
						||
TMP__PIECEALGO=${PIECEALGO-${TMP_RANDOM}}
 | 
						||
TMP_aptfast_prefix="${aptfast_prefix-${TMP_RANDOM}}"
 | 
						||
TMP_APT_FAST_TIMEOUT="${APT_FAST_TIMEOUT-${TMP_RANDOM}}"
 | 
						||
TMP_VERBOSE_OUTPUT="${VERBOSE_OUTPUT-${TMP_RANDOM}}"
 | 
						||
TMP_ftp_proxy="${ftp_proxy-${TMP_RANDOM}}"
 | 
						||
TMP_http_proxy="${http_proxy-${TMP_RANDOM}}"
 | 
						||
TMP_https_proxy="${https_proxy-${TMP_RANDOM}}"
 | 
						||
 | 
						||
# Check for proper privileges.
 | 
						||
# Call explicitly with environment variables to get them into root conext.
 | 
						||
if [ "$root" = 1 ] && [ "$UID" != 0 ]; then
 | 
						||
  exec sudo DEBUG="$DEBUG" \
 | 
						||
            LCK_FILE="$TMP_LCK_FILE" \
 | 
						||
            DOWNLOADBEFORE="$TMP_DOWNLOADBEFORE" \
 | 
						||
            _APTMGR="$TMP__APTMGR" \
 | 
						||
            APTCACHE="$TMP_APTCACHE" \
 | 
						||
            DLDIR="$TMP_DLDIR" \
 | 
						||
            DLLIST="$TMP_DLLIST" \
 | 
						||
            LISTDIR="$TMP_LISTDIR" \
 | 
						||
            _MAXNUM="$TMP__MAXNUM" \
 | 
						||
            _MAXCONPERSRV="$TMP__MAXCONPERSRV" \
 | 
						||
            _SPLITCON="$TMP__SPLITCON" \
 | 
						||
            _MINSPLITSZ="$TMP__MINSPLITSZ" \
 | 
						||
            _PIECEALGO="$TMP__PIECEALGO" \
 | 
						||
            aptfast_prefix="$TMP_aptfast_prefix" \
 | 
						||
            APT_FAST_TIMEOUT="$TMP_APT_FAST_TIMEOUT" \
 | 
						||
            VERBOSE_OUTPUT="$TMP_VERBOSE_OUTPUT" \
 | 
						||
            ftp_proxy="$TMP_ftp_proxy" \
 | 
						||
            http_proxy="$TMP_http_proxy" \
 | 
						||
            https_proxy="$TMP_https_proxy" \
 | 
						||
            "$0" "$@"
 | 
						||
fi
 | 
						||
 | 
						||
 | 
						||
# Define lockfile.
 | 
						||
# Use /tmp as directory because everybody (not only root) has to have write
 | 
						||
# permissions.
 | 
						||
# We need lock for non-root commands too, because we only have one download
 | 
						||
# list file.
 | 
						||
if [ "$IS_ACE_ENV" != "" ];then
 | 
						||
LCK_FILE="/tmp/apt-fast-in-container.lock"
 | 
						||
else
 | 
						||
LCK_FILE="/tmp/apt-fast.lock"
 | 
						||
fi
 | 
						||
LCK_FD=99
 | 
						||
 | 
						||
# Set default package manager, APT cache, temporary download dir,
 | 
						||
# temporary download list file, and maximal parallel downloads
 | 
						||
_APTMGR=apt-get
 | 
						||
eval "$(apt-config shell APTCACHE Dir::Cache::archives/d)"
 | 
						||
# Check if APT config option Dir::Cache::archives::apt-fast-partial is set.
 | 
						||
eval "$(apt-config shell apt_fast_partial Dir::Cache::archives::apt-fast-partial/d)"
 | 
						||
if [ -z "$apt_fast_partial" ]; then
 | 
						||
  eval "$(apt-config -o Dir::Cache::archives::apt-fast-partial=apt-fast shell DLDIR Dir::Cache::archives::apt-fast-partial/d)"
 | 
						||
else
 | 
						||
  eval "$(apt-config shell DLDIR Dir::Cache::archives::apt-fast-partial/d)"
 | 
						||
fi
 | 
						||
# Currently not needed.
 | 
						||
eval "$(apt-config shell LISTDIR Dir::State::lists/d)"
 | 
						||
if [ "$IS_ACE_ENV" != "" ];then
 | 
						||
DLLIST="/tmp/apt-fast-in-container.list"
 | 
						||
else
 | 
						||
DLLIST="/tmp/apt-fast.list"
 | 
						||
fi
 | 
						||
_MAXNUM=5
 | 
						||
_MAXCONPERSRV=10
 | 
						||
_SPLITCON=8
 | 
						||
_MINSPLITSZ="1M"
 | 
						||
_PIECEALGO="default"
 | 
						||
 | 
						||
# Prefix in front of apt-fast output:
 | 
						||
aptfast_prefix=
 | 
						||
# aptfast_prefix="$(date '+%b %_d %T.%N') apt-fast: "
 | 
						||
 | 
						||
# Set color variables.
 | 
						||
cGreen='\e[0;32m'
 | 
						||
cRed='\e[0;31m'
 | 
						||
cBlue='\e[0;34m'
 | 
						||
endColor='\e[0m'
 | 
						||
 | 
						||
# Set timout value for apt-fast download confirmation dialog.
 | 
						||
# Value is in seconds.
 | 
						||
APT_FAST_TIMEOUT=60
 | 
						||
 | 
						||
# Ask for download confirmation if unset
 | 
						||
DOWNLOADBEFORE=
 | 
						||
 | 
						||
# Formatted package list in download confirmation if unset
 | 
						||
VERBOSE_OUTPUT=
 | 
						||
 | 
						||
# Download command.
 | 
						||
_DOWNLOADER='aria2c --no-conf -c -j ${_MAXNUM} -x ${_MAXCONPERSRV} -s ${_SPLITCON} -i ${DLLIST} --min-split-size=${_MINSPLITSZ} --stream-piece-selector=${_PIECEALGO} --connect-timeout=60 --timeout=600 -m0'
 | 
						||
 | 
						||
# Load config file.
 | 
						||
CONFFILE="/tmp/aptss-conf/apt-fast.conf"
 | 
						||
#### Spark Store apt-fast conf is in /tmp
 | 
						||
if [ -e "$CONFFILE" ]; then
 | 
						||
    source "$CONFFILE"
 | 
						||
fi
 | 
						||
 | 
						||
# no proxy as default
 | 
						||
ftp_proxy=
 | 
						||
http_proxy=
 | 
						||
https_proxy=
 | 
						||
 | 
						||
# Now overwrite with preserved values if values were set before (compare with
 | 
						||
# 'random' string).
 | 
						||
[ "$TMP_LCK_FILE" = "$TMP_RANDOM" ] || LCK_FILE="$TMP_LCK_FILE"
 | 
						||
[ "$TMP_DOWNLOADBEFORE" = "$TMP_RANDOM" ] || DOWNLOADBEFORE="$TMP_DOWNLOADBEFORE"
 | 
						||
[ "$TMP__APTMGR" = "$TMP_RANDOM" ] || _APTMGR="$TMP__APTMGR"
 | 
						||
[ "$TMP_APTCACHE" = "$TMP_RANDOM" ] || APTCACHE="$TMP_APTCACHE"
 | 
						||
[ "$TMP_DLDIR" = "$TMP_RANDOM" ] || DLDIR="$TMP_DLDIR"
 | 
						||
[ "$TMP_DLLIST" = "$TMP_RANDOM" ] || DLLIST="$TMP_DLLIST"
 | 
						||
[ "$TMP_LISTDIR" = "$TMP_RANDOM" ] || LISTDIR="$TMP_LISTDIR"
 | 
						||
[ "$TMP__MAXNUM" = "$TMP_RANDOM" ] || _MAXNUM="$TMP__MAXNUM"
 | 
						||
[ "$TMP__MAXCONPERSRV" = "$TMP_RANDOM" ] || _MAXCONPERSRV="$TMP__MAXCONPERSRV"
 | 
						||
[ "$TMP__SPLITCON" = "$TMP_RANDOM" ] || _SPLITCON="$TMP__SPLITCON"
 | 
						||
[ "$TMP__MINSPLITSZ" = "$TMP_RANDOM" ] || _MINSPLITSZ="$TMP__MINSPLITSZ"
 | 
						||
[ "$TMP__PIECEALGO" = "$TMP_RANDOM" ] || _PIECEALGO="$TMP__PIECEALGO"
 | 
						||
[ "$TMP_aptfast_prefix" = "$TMP_RANDOM" ] || aptfast_prefix="$TMP_aptfast_prefix"
 | 
						||
[ "$TMP_APT_FAST_TIMEOUT" = "$TMP_RANDOM" ] || APT_FAST_TIMEOUT="$TMP_APT_FAST_TIMEOUT"
 | 
						||
[ "$TMP_VERBOSE_OUTPUT" = "$TMP_RANDOM" ] || VERBOSE_OUTPUT="$TMP_VERBOSE_OUTPUT"
 | 
						||
[ "$TMP_ftp_proxy" = "$TMP_RANDOM" ] || ftp_proxy="$TMP_ftp_proxy"
 | 
						||
[ "$TMP_http_proxy" = "$TMP_RANDOM" ] || http_proxy="$TMP_http_proxy"
 | 
						||
[ "$TMP_https_proxy" = "$TMP_RANDOM" ] || https_proxy="$TMP_https_proxy"
 | 
						||
 | 
						||
 | 
						||
# Disable colors if not executed in terminal.
 | 
						||
if [ ! -t 1 ]; then
 | 
						||
  cGreen=
 | 
						||
  cRed=
 | 
						||
  cBlue=
 | 
						||
  endColor=
 | 
						||
  #FIXME: Time not updated.
 | 
						||
  [ -z "$aptfast_prefix" ] && aptfast_prefix="[apt-fast $(date +"%T")]"
 | 
						||
fi
 | 
						||
 | 
						||
 | 
						||
msg_already_running()
 | 
						||
{
 | 
						||
  msg "Other aptss is running.  Waited $timer senconds..." "normal"
 | 
						||
  msg "有其他的aptss正在运行。已经等待了$timer秒" "normal"
 | 
						||
}
 | 
						||
 | 
						||
# Check if a lock file exists.
 | 
						||
#if [ -f "$LCK_FILE.lock" ]; then
 | 
						||
#  msg_already_running
 | 
						||
#  exit 1
 | 
						||
#fi
 | 
						||
 | 
						||
 | 
						||
# create the lock file and lock it, die on failure
 | 
						||
_create_lock()
 | 
						||
{
 | 
						||
    eval "exec $LCK_FD>\"$LCK_FILE.lock\""
 | 
						||
 | 
						||
#    trap "cleanup_aptfast; exit_cleanup_state" EXIT
 | 
						||
#    This will hide the exit code
 | 
						||
    trap "cleanup_aptfast" EXIT
 | 
						||
    trap "cleanup_aptfast; exit 1" INT TERM
 | 
						||
	timer=0
 | 
						||
	until $(flock -xn $LCK_FD);do 
 | 
						||
	msg_already_running
 | 
						||
	sleep 1
 | 
						||
	let timer+=1
 | 
						||
	done
 | 
						||
	unset timer
 | 
						||
}
 | 
						||
 | 
						||
# unlock and remove the lock file
 | 
						||
_remove_lock()
 | 
						||
{
 | 
						||
    flock -u "$LCK_FD" 2>/dev/null
 | 
						||
    rm -f "$LCK_FILE.lock"
 | 
						||
}
 | 
						||
 | 
						||
# Move download file away so missing permissions won't stop usage.
 | 
						||
CLEANUP_STATE=0
 | 
						||
cleanup_dllist()
 | 
						||
{
 | 
						||
  if [ -f "$DLLIST" ]
 | 
						||
  then
 | 
						||
    if ! mv -- "$DLLIST{,.old}" 2>/dev/null
 | 
						||
    then
 | 
						||
      if ! rm -f -- "$DLLIST" 2>/dev/null
 | 
						||
      then
 | 
						||
        msg "Could not clean up download list file." "warning"
 | 
						||
        msg "无法清除下载列表文件." "warning"
 | 
						||
        CLEANUP_STATE=1
 | 
						||
      fi
 | 
						||
    fi
 | 
						||
  fi
 | 
						||
}
 | 
						||
 | 
						||
cleanup_aptfast()
 | 
						||
{
 | 
						||
  [ "$CLEANUP_STATE" -eq 0 ] && CLEANUP_STATE=$?
 | 
						||
  cleanup_dllist
 | 
						||
  _remove_lock
 | 
						||
}
 | 
						||
 | 
						||
exit_cleanup_state()
 | 
						||
{
 | 
						||
  exit $CLEANUP_STATE
 | 
						||
}
 | 
						||
 | 
						||
# decode url string
 | 
						||
# translates %xx but must not convert '+' in spaces
 | 
						||
urldecode()
 | 
						||
{
 | 
						||
    printf '%b' "${1//%/\\x}"
 | 
						||
}
 | 
						||
 | 
						||
# Check if mirrors are available. And if so add all mirrors to download list.
 | 
						||
############ SPARK ADJUST: Now we ignore the first config for business request
 | 
						||
get_mirrors(){
 | 
						||
  # Check all mirror lists.
 | 
						||
  for mirrorstr in "${MIRRORS[@]}"; do
 | 
						||
    # Build mirrors array from comma separated string.
 | 
						||
    IFS=", " read -r -a mirrors <<< "$mirrorstr"
 | 
						||
    # Check for all mirrors if URI of $1 is from mirror. If so add all other
 | 
						||
    # mirrors to (resmirror) list and break all loops.
 | 
						||
    for mirror in "${mirrors[@]}"; do
 | 
						||
      # Real expension.
 | 
						||
      if [[ "$1" == "$mirror"* ]]; then
 | 
						||
        filepath=${1#${mirror}}
 | 
						||
        # Build list for aria download list.
 | 
						||
        list="${mirrors[*]:1}"
 | 
						||
        echo -e "${list// /${filepath}\\t}$filepath\n"
 | 
						||
        return 0
 | 
						||
      fi
 | 
						||
    done
 | 
						||
  done
 | 
						||
  # No other mirrors found.
 | 
						||
  echo "$1"
 | 
						||
}
 | 
						||
##########SPARK ADJUST: END
 | 
						||
# Globals to save package name, version, size and overall size.
 | 
						||
DOWNLOAD_DISPLAY=
 | 
						||
DOWNLOAD_SIZE=0
 | 
						||
 | 
						||
# Get the package URLs.
 | 
						||
get_uris(){
 | 
						||
 | 
						||
  if [ ! -d "$(dirname "$DLLIST")" ]
 | 
						||
  then
 | 
						||
    if ! mkdir -p -- "$(dirname "$DLLIST")"
 | 
						||
    then
 | 
						||
      msg "Could not create download file directory." "warning"
 | 
						||
      msg "无法创建下载文件夹" "warning"
 | 
						||
      exit 1
 | 
						||
    fi
 | 
						||
  elif [ -f "$DLLIST" ]; then
 | 
						||
    if ! rm -f -- "$DLLIST" 2>/dev/null && ! touch -- "$DLLIST" 2>/dev/null
 | 
						||
    then
 | 
						||
      msg "Unable to write to download file. Try restarting with root permissions or run 'aptss clean' first." "warning"
 | 
						||
      msg "无法下载文件。尝试使用root权限,或者运行 'aptss clean'" "warning"
 | 
						||
      exit 1
 | 
						||
    fi
 | 
						||
  fi
 | 
						||
 | 
						||
  # Add header to overwrite file.
 | 
						||
  echo "# apt-fast mirror list: $(date)" > "$DLLIST"
 | 
						||
  #NOTE: aptitude doesn't have this functionality, so we use apt-get to get
 | 
						||
  #      package URIs.
 | 
						||
#  case "$_APTMGR" in
 | 
						||
#    apt|apt-get) uri_mgr=$_APTMGR;;
 | 
						||
#    *) uri_mgr=apt-get;;
 | 
						||
#  esac
 | 
						||
  # NOTE:apt可能出现变动,不建议在脚本中使用,因此在此统一改用apt-get
 | 
						||
uri_mgr=apt-get
 | 
						||
  uris_full="$("$uri_mgr" "${APT_SCRIPT_WARNING[@]}" -y --print-uris "$@")"
 | 
						||
  uris_full_ret="$?"
 | 
						||
  if [ "$uris_full_ret" -ne 0 ]
 | 
						||
  then
 | 
						||
    msg "Package manager quit with exit code.Here is the log" "warning"
 | 
						||
    msg "包管理器以错误代码退出.日志如下" "warning"
 | 
						||
    msg "${uris_full}"
 | 
						||
    exit "$uris_full_ret"
 | 
						||
  fi
 | 
						||
  while read -r pkg_uri_info
 | 
						||
  do
 | 
						||
    [ -z "$pkg_uri_info" ] && continue
 | 
						||
    ## --print-uris format is:
 | 
						||
    # 'fileurl' filename filesize checksum_hint:filechecksum
 | 
						||
    uri="$(echo "$pkg_uri_info" | cut -d' ' -f1 | tr -d "'")"
 | 
						||
    filename="$(echo "$pkg_uri_info" | cut -d' ' -f2)"
 | 
						||
    filesize="$(echo "$pkg_uri_info" | cut -d' ' -f3)"
 | 
						||
    checksum_string="$(echo "$pkg_uri_info" | cut -d' ' -f4)"
 | 
						||
    hash_algo="$(echo "$checksum_string" | cut -d':' -f1)"
 | 
						||
    checksum="$(echo "$checksum_string" | cut -d':' -f2)"
 | 
						||
 | 
						||
    filename_decoded="$(urldecode "$filename")"
 | 
						||
    DOWNLOAD_DISPLAY="${DOWNLOAD_DISPLAY}$(echo "$filename_decoded" | cut -d'_' -f1)"
 | 
						||
    DOWNLOAD_DISPLAY="${DOWNLOAD_DISPLAY} $(echo "$filename_decoded" | cut -d'_' -f2)"
 | 
						||
    DOWNLOAD_DISPLAY="${DOWNLOAD_DISPLAY} $(echo "$filesize" | numfmt --to=iec-i --suffix=B)\n"
 | 
						||
    DOWNLOAD_SIZE=$((DOWNLOAD_SIZE + filesize))
 | 
						||
 | 
						||
    ## whole uri comes encoded (urlencoded). Filename must NOT be decoded because
 | 
						||
    # plain aptitude do not decode it when download and install it. Therefore, we
 | 
						||
    # will have ugly named packages at /var/cache/apt/archives but is the standard
 | 
						||
    # behavior.
 | 
						||
    # But package version must be decoded, otherways package=version calls will
 | 
						||
    # not work.
 | 
						||
 | 
						||
    if [ -n "$HASH_SUPPORTED" ]; then
 | 
						||
      case "$hash_algo" in
 | 
						||
        SHA512) [ -z "$SHA512_SUPPORTED" ] && hash_algo= || hash_algo=sha-512 ;;
 | 
						||
        SHA256) [ -z "$SHA256_SUPPORTED" ] && hash_algo= || hash_algo=sha-256 ;;
 | 
						||
        SHA1)   [ -z "$SHA1_SUPPORTED" ]   && hash_algo= || hash_algo=sha-1 ;;
 | 
						||
        MD5Sum) [ -z "$MD5sum_SUPPORTED" ] && hash_algo= || hash_algo=md5 ;;
 | 
						||
        *) hash_algo=
 | 
						||
      esac
 | 
						||
 | 
						||
      # Using apt-cache show package=version to ensure recover single and
 | 
						||
      # correct package version.
 | 
						||
      # Warning: assuming that package naming uses '_' as field separator.
 | 
						||
      # Therefore, this code expects package-name_version_arch.deb Otherways
 | 
						||
      # below code will fail resoundingly
 | 
						||
      if [ -z "$hash_algo" ]; then
 | 
						||
        pkg_name="$(echo "$filename" | cut -d'_' -f1)"
 | 
						||
        pkg_version="$(echo "$filename" | cut -d'_' -f2)"
 | 
						||
        pkg_version="$(urldecode "$pkg_version")"
 | 
						||
        package_info="$(apt-cache show "$pkg_name=$pkg_version")"
 | 
						||
 | 
						||
        patch_checksum=
 | 
						||
        if [ -n "$SHA512_SUPPORTED" ]; then
 | 
						||
          patch_checksum="$(echo "$package_info" | grep SHA512 | head -n 1)"
 | 
						||
          [ -n "$patch_checksum" ] && hash_algo="sha-512"
 | 
						||
        fi
 | 
						||
        if [ -z "$patch_checksum" ] && [ -n "$SHA256_SUPPORTED" ]; then
 | 
						||
          patch_checksum="$(echo "$package_info" | grep SHA256 | head -n 1)"
 | 
						||
          [ -n "$patch_checksum" ] && hash_algo="sha-256"
 | 
						||
        fi
 | 
						||
        if [ -z "$patch_checksum" ] && [ -n "$SHA1_SUPPORTED" ]; then
 | 
						||
          patch_checksum="$(echo "$package_info" | grep SHA1 | head -n 1)"
 | 
						||
          [ -n "$patch_checksum" ] && hash_algo="sha-1"
 | 
						||
        fi
 | 
						||
        if [ -z "$patch_checksum" ] && [ -n "$MD5sum_SUPPORTED" ]; then
 | 
						||
          patch_checksum="$(echo "$package_info" | grep MD5sum | head -n 1)"
 | 
						||
          [ -n "$patch_checksum" ] && hash_algo="md5"
 | 
						||
        fi
 | 
						||
 | 
						||
        if [ -n "$patch_checksum" ]; then
 | 
						||
          checksum="$(echo "$patch_checksum" | cut -d' ' -f2)"
 | 
						||
        else
 | 
						||
          msg "Couldn't get supported checksum for $pkg_name ($pkg_version)." "warning"
 | 
						||
	  msg "无法获得 $pkg_name ($pkg_version) 的受支持的散列验证值" "warning"
 | 
						||
          REMOVE_WORKING_MESSAGE=
 | 
						||
        fi
 | 
						||
      fi
 | 
						||
    else
 | 
						||
      hash_algo=
 | 
						||
    fi
 | 
						||
 | 
						||
    {
 | 
						||
      get_mirrors "$uri"
 | 
						||
      #echo " dir=$DLDIR"
 | 
						||
      if [ -n "$hash_algo" ]; then
 | 
						||
        echo " checksum=$hash_algo=$checksum"
 | 
						||
      fi
 | 
						||
      echo " out=$filename"
 | 
						||
    } >> "$DLLIST"
 | 
						||
  done <<<"$(echo "$uris_full" | grep -E "^'(http(s|)|(s|)ftp)://")"
 | 
						||
 | 
						||
  #cat "$DLLIST"
 | 
						||
  #LCK_RM
 | 
						||
  #exit
 | 
						||
}
 | 
						||
 | 
						||
display_downloadfile(){
 | 
						||
  if [ -n "$VERBOSE_OUTPUT" ]; then
 | 
						||
    cat "$DLLIST"
 | 
						||
  else
 | 
						||
    DISPLAY_SORT_OPTIONS=(-k 1,1)
 | 
						||
    # Sort output after package download size (decreasing):
 | 
						||
    #DISPLAY_SORT_OPTIONS=(-k 3,3 -hr)
 | 
						||
    while read -r line; do
 | 
						||
        [ -z "$line" ] && continue
 | 
						||
        pkg="$(echo "$line" | cut -d' ' -f1)"
 | 
						||
        ver="$(echo "$line" | cut -d' ' -f2)"
 | 
						||
        size="$(echo "$line" | cut -d' ' -f3)"
 | 
						||
        printf '%s%-40s %-20s %10s\n' "$aptfast_prefix" "$pkg" "$ver" "$size"
 | 
						||
    done <<<"$(echo -e "$DOWNLOAD_DISPLAY" | sort "${DISPLAY_SORT_OPTIONS[@]}")"
 | 
						||
  fi
 | 
						||
  msg "Download size: $(echo "$DOWNLOAD_SIZE" | numfmt --to=iec-i --suffix=B)" "normal"
 | 
						||
  msg "下载大小: $(echo "$DOWNLOAD_SIZE" | numfmt --to=iec-i --suffix=B)" "normal"
 | 
						||
}
 | 
						||
 | 
						||
# Create and insert a PID number to lockfile.
 | 
						||
 | 
						||
_create_lock
 | 
						||
 | 
						||
# Make sure aria2c (in general first parameter from _DOWNLOADER) is available.
 | 
						||
CMD="$(echo "$_DOWNLOADER" | sed 's/^\s*\([^ ]\+\).*$/\1/')"
 | 
						||
if [ ! "$(command -v "$CMD")" ]; then
 | 
						||
  msg "Command not found: $CMD" "normal" "err"
 | 
						||
  msg "You must configure $CONFFILE to use aria2c or another supported download manager" "normal" "err"
 | 
						||
  exit 1
 | 
						||
fi
 | 
						||
 | 
						||
# Make sure package manager is available.
 | 
						||
if [ ! "$(command -v "$_APTMGR")" ]; then
 | 
						||
  msg "\`$_APTMGR\` command not available." "warning"
 | 
						||
  msg "You must configure $CONFFILE to use either apt-get or aptitude." "normal" "err"
 | 
						||
  exit 1
 | 
						||
fi
 | 
						||
 | 
						||
# Disable script warning if apt is used.
 | 
						||
APT_SCRIPT_WARNING=()
 | 
						||
if [ "$_APTMGR" == "apt" ]; then
 | 
						||
    APT_SCRIPT_WARNING=(-o "Apt::Cmd::Disable-Script-Warning=true")
 | 
						||
fi
 | 
						||
 | 
						||
# Set supported hash algorithms by aria2c (and also by Debian repository).
 | 
						||
SHA512_SUPPORTED=
 | 
						||
SHA256_SUPPORTED=
 | 
						||
SHA1_SUPPORTED=
 | 
						||
MD5sum_SUPPORTED=
 | 
						||
HASH_SUPPORTED=
 | 
						||
if [ "$CMD" == "aria2c" ]; then
 | 
						||
  for supported_hash in $(LC_ALL=C aria2c -v | sed '/^Hash Algorithms:/!d; s/\(^Hash Algorithms: \|,\)\+//g'); do
 | 
						||
    case "$supported_hash" in
 | 
						||
      sha-512) SHA512_SUPPORTED=y; HASH_SUPPORTED=y ;;
 | 
						||
      sha-256) SHA256_SUPPORTED=y; HASH_SUPPORTED=y ;;
 | 
						||
      sha-1)   SHA1_SUPPORTED=y;   HASH_SUPPORTED=y ;;
 | 
						||
      md5)     MD5sum_SUPPORTED=y; HASH_SUPPORTED=y ;;
 | 
						||
    esac
 | 
						||
  done
 | 
						||
  if [ -z "$HASH_SUPPORTED" ]; then
 | 
						||
    msg "Couldn't find supported checksum algorithm from aria2c. Checksums disabled." "warning"
 | 
						||
    msg "无法找到aria2c支持的散列验证算法. 散列验证已被禁用." "warning"
 | 
						||
  fi
 | 
						||
fi
 | 
						||
 | 
						||
# Check if "assume yes" switch is enabled and if yes enable $DOWNLOADBEFORE.
 | 
						||
# Also check if "download only" switch is enabled.
 | 
						||
#TODO: Get real value over APT items APT::Get::Assume-Yes and
 | 
						||
#      APT::Get::Assume-No .
 | 
						||
#      Respectively Aptitude::CmdLine::Download-Only and APT::Get::Download-Only.
 | 
						||
DOWNLOAD_ONLY=
 | 
						||
while true; do
 | 
						||
  while getopts ":dy-:" optchar; do
 | 
						||
    case "${optchar}" in
 | 
						||
      -)
 | 
						||
        case "${OPTARG}" in
 | 
						||
          yes | assume-yes)  DOWNLOADBEFORE=true ;;
 | 
						||
          assume-no)         DOWNLOADBEFORE=     ;;
 | 
						||
          download-only)     DOWNLOAD_ONLY=true  ;;
 | 
						||
        esac
 | 
						||
        ;;
 | 
						||
      y)
 | 
						||
        DOWNLOADBEFORE=true
 | 
						||
        ;;
 | 
						||
      d)
 | 
						||
        DOWNLOAD_ONLY=true
 | 
						||
        ;;
 | 
						||
    esac
 | 
						||
  done
 | 
						||
  ((OPTIND++))
 | 
						||
  [ $OPTIND -gt $# ] && break
 | 
						||
done
 | 
						||
 | 
						||
# Configure proxies. Use apt values over environment variables.
 | 
						||
# Note: If proxy setting is not set, there is no apt-config output.
 | 
						||
#       Therefore variable doesn't get overriden, which is intended.
 | 
						||
# Export the variables to make them available in subshells (aka the
 | 
						||
# downloader command).
 | 
						||
eval "$(apt-config shell ftp_proxy Acquire::ftp::proxy)"
 | 
						||
export ftp_proxy
 | 
						||
eval "$(apt-config shell http_proxy Acquire::http::proxy)"
 | 
						||
export http_proxy
 | 
						||
eval "$(apt-config shell https_proxy Acquire::https::proxy)"
 | 
						||
export https_proxy
 | 
						||
 | 
						||
# aria2 has no socks support (see https://github.com/aria2/aria2/issues/153)
 | 
						||
if echo "$http_proxy" | grep -q "^socks5h://" || echo "$https_proxy" | grep -q "^socks5h://"; then
 | 
						||
  msg "Socks proxy detected. Falling back to ${_APTMGR}" "hint"
 | 
						||
  "${_APTMGR}" "${APT_SCRIPT_WARNING[@]}" "$@"
 | 
						||
  exit 0
 | 
						||
fi
 | 
						||
 | 
						||
# Run actions.
 | 
						||
if [ "$option" == "install" ]; then
 | 
						||
  msg
 | 
						||
  msg "Working... this may take a while." "normal"
 | 
						||
  msg "正在工作中,请稍等" "normal"
 | 
						||
  REMOVE_WORKING_MESSAGE=y
 | 
						||
 | 
						||
  get_uris "$@"
 | 
						||
  [ -t 1 ] && [ -n "$REMOVE_WORKING_MESSAGE" ] && tput cuu 1 && tput el && tput cuu 1
 | 
						||
  # Test /tmp/apt-fast.list file exists and not just the apt-fast comment line.
 | 
						||
  # Then download all files from the list.
 | 
						||
  if [ -f "$DLLIST" ] && [ "$(wc -l "$DLLIST" | cut -d' ' -f1)" -gt 1 ] && [ ! "$DOWNLOADBEFORE" ]; then
 | 
						||
    display_downloadfile
 | 
						||
    msg
 | 
						||
    msg "Do you want to download the packages? [Y/n] " "question"
 | 
						||
 | 
						||
    while ((!updsys)); do
 | 
						||
      read -r -sn1 -t "$APT_FAST_TIMEOUT" answer || { msg; msg "Timed out." "warning"; exit 1; }
 | 
						||
      case "$answer" in
 | 
						||
        [JjYy])    result=1; updsys=1 ;;
 | 
						||
        [Nn])      result=0; updsys=1 ;;
 | 
						||
        "")        result=1; updsys=1 ;;
 | 
						||
        *)         updsys=0 ;;
 | 
						||
      esac
 | 
						||
    done
 | 
						||
  else
 | 
						||
    result=1
 | 
						||
  fi
 | 
						||
 | 
						||
  if ((DOWNLOAD_SIZE)); then
 | 
						||
    msg
 | 
						||
    # Continue if answer was right or DOWNLOADBEFORE is enabled.
 | 
						||
    if ((result)); then
 | 
						||
      if [ -s "$DLLIST" ]; then
 | 
						||
        # Test if apt-fast directory is present where we put packages.
 | 
						||
        if [ ! -d "$DLDIR" ]; then
 | 
						||
          mkdir -p -- "$DLDIR"
 | 
						||
        fi
 | 
						||
 | 
						||
        cd "$DLDIR" &>/dev/null || exit 1
 | 
						||
 | 
						||
        eval "${_DOWNLOADER}"  # execute downloadhelper command
 | 
						||
        if [ "$(find "$DLDIR" -printf . | wc -c)" -gt 1 ]; then
 | 
						||
 | 
						||
          # Delete incomplete/corrupted downloaded files, if any: Not recursive, as we don't expect any dirs to exist within $DLDIR.
 | 
						||
 | 
						||
          # When Aria2c downloads a file and detects it is corrupted, its filename won't be renamed back to its actual name,
 | 
						||
          # preserving .aria2 file extension, which also indicates when a file hasn't been completely downloaded.
 | 
						||
          for x in *.aria2; do
 | 
						||
            rm -f "$x" "${x%.aria2}"
 | 
						||
          done
 | 
						||
 | 
						||
          # Move all packages to the apt install directory by force to ensure
 | 
						||
          # already existing debs which may be incomplete are replaced
 | 
						||
          find . -type f \( -name '*.deb' -o -name '*.ddeb' \) -execdir mv -ft "$APTCACHE" {} \+
 | 
						||
        fi
 | 
						||
        cd - &>/dev/null || msg "Failed to change back directory" "warning"
 | 
						||
      fi
 | 
						||
    else
 | 
						||
      exit 1
 | 
						||
    fi
 | 
						||
  else
 | 
						||
    [ -t 1 ] && tput el
 | 
						||
  fi
 | 
						||
 | 
						||
  if [ -z "$DOWNLOAD_ONLY" ] || [ "$_APTMGR" == "aptitude" ]; then
 | 
						||
    "${_APTMGR}" "${APT_SCRIPT_WARNING[@]}" "$@"
 | 
						||
  fi
 | 
						||
 | 
						||
 | 
						||
elif [ "$option" == "clean" ]; then
 | 
						||
  "${_APTMGR}" "${APT_SCRIPT_WARNING[@]}" "$@" && {
 | 
						||
    find "$DLDIR" -maxdepth 1 -type f -delete
 | 
						||
    CLEANUP_STATE="$?"
 | 
						||
    [ -f "$DLLIST" ] && rm -f -- "$DLLIST"* || true
 | 
						||
  }
 | 
						||
 | 
						||
elif [ "$option" == "download" ]; then
 | 
						||
  msg
 | 
						||
  msg "Working... this may take a while." "normal"
 | 
						||
  msg "正在工作中,请稍等" "normal"
 | 
						||
  REMOVE_WORKING_MESSAGE=y
 | 
						||
 | 
						||
  get_uris "$@"
 | 
						||
 | 
						||
  [ -t 1 ] && [ -n "$REMOVE_WORKING_MESSAGE" ] && tput cuu 1 && tput el && tput cuu 1
 | 
						||
 | 
						||
  if [ -f "$DLLIST" ] && [ "$(wc -l "$DLLIST" | cut -d' ' -f1)" -gt 1 ]; then
 | 
						||
    display_downloadfile
 | 
						||
    eval "${_DOWNLOADER}"
 | 
						||
  fi
 | 
						||
 | 
						||
  if [ "$_APTMGR" == "aptitude" ]; then
 | 
						||
    "${_APTMGR}" "$@"
 | 
						||
  fi
 | 
						||
 | 
						||
elif [ "$option" == "source" ]; then
 | 
						||
  msg
 | 
						||
  msg "Working... this may take a while." "normal"
 | 
						||
  msg "正在工作中,请稍等" "normal"
 | 
						||
  REMOVE_WORKING_MESSAGE=y
 | 
						||
 | 
						||
  get_uris "$@"
 | 
						||
 | 
						||
  [ -t 1 ] && [ -n "$REMOVE_WORKING_MESSAGE" ] && tput cuu 1 && tput el && tput cuu 1
 | 
						||
 | 
						||
  if [ -f "$DLLIST" ] && [ "$(wc -l "$DLLIST" | cut -d' ' -f1)" -gt 1 ]; then
 | 
						||
    display_downloadfile
 | 
						||
    eval "${_DOWNLOADER}"
 | 
						||
  fi
 | 
						||
  # We use APT manager here to provide more verbose output. This method is
 | 
						||
  # slightly slower then extractiong packages manually after download but also
 | 
						||
  # more hardened (e.g. some options like --compile are available).
 | 
						||
  "${_APTMGR}" "${APT_SCRIPT_WARNING[@]}" "$@"
 | 
						||
  # Uncomment following snippet to extract source directly and comment
 | 
						||
  # both lines before.
 | 
						||
  #while read srcfile; do
 | 
						||
  #  # extract only .dsc files
 | 
						||
  #  echo "$srcfile" | grep -q '\.dsc$' || continue
 | 
						||
  #  dpkg-source -x "$(basename "$srcfile")"
 | 
						||
  #done < "$DLLIST"
 | 
						||
 | 
						||
# Execute package manager directly if unknown options are passed.
 | 
						||
else
 | 
						||
  "${_APTMGR}" "${APT_SCRIPT_WARNING[@]}" "$@"
 | 
						||
fi
 | 
						||
 | 
						||
# After error or all done remove our lockfile (done with EXIT trap)
 |