From 6a757a93556770f227be9bdd85ce68c44d047777 Mon Sep 17 00:00:00 2001 From: davidovski Date: Tue, 12 Apr 2022 12:16:47 +0100 Subject: added serial downloads and checking for root --- src/get.sh | 87 ++++++++++++++++++++++++++++++++++++++++++---------------- src/install.sh | 30 +++++++++----------- src/remove.sh | 7 ++--- src/util.sh | 6 +++- src/xi.sh | 7 +++++ 5 files changed, 91 insertions(+), 46 deletions(-) diff --git a/src/get.sh b/src/get.sh index b99340f..d4a70a0 100755 --- a/src/get.sh +++ b/src/get.sh @@ -1,6 +1,5 @@ #!/bin/sh - # list all direct dependencies of a package # list_deps() { @@ -52,14 +51,23 @@ resolve_deps () { echo ${deps} > $out } +# get the download info for a package ($1) +# +# in format: +# url checksum size files +# get_package_download_info() { sed 1q ${PACKAGES_DIR}/*/$1 } +# return if a package is present on the system or not +# is_installed() { [ -f "${INSTALLED_DIR}/$1/checksum" ] } +# get the installed checksum of a package ($1) +# get_installed_version () { local name=$1 local file="${INSTALLED_DIR}/$name/checksum" @@ -91,30 +99,37 @@ download_package () { ${VERBOSE} && printf "${LIGHT_BLACK}downloading $package from $url\n" $package $checksum touch $output - (curl ${CURL_OPTS} -o "$output_info" "$url.info" 2>> ${LOG_FILE} || printf "${RED}Failed to download info for %s\n" $package) & - (curl ${CURL_OPTS} -o "$output" "$url" 2>> ${LOG_FILE} || printf "${RED}Failed to download %s\n" $package) & + (curl ${CURL_OPTS} -o "$output_info" "$url.info" 2>> ${LOG_FILE} || printf "${RED}Failed to download info for %s\n" $package) + (curl ${CURL_OPTS} -o "$output" "$url" 2>> ${LOG_FILE} || printf "${RED}Failed to download %s\n" $package) } +# download a list of packages +# will download, verify and install the packages +# +# total_download: total number of bytes to download +# packages: list of packages by name to download +# download_packages () { local total_download=$1; shift - local packages=$@ local outputs="" local out_dir="${PACKAGE_CACHE}" mkdir -p "$out_dir" - for package in $packages; do - local output="${out_dir}/${checksum}.${package}.xipkg" - download_package $package $output - outputs="$outputs $output" + for package in $@; do + outputs="$outputs ${out_dir}/${checksum}.${package}.xipkg" done + fetch_serial $total_download $outputs - wait_for_download $total_download ${outputs} - - set -- $outputs + validate_downloads $outputs +} +# validate signatures of downloaded packages +# +# outputs: list of xipkg files to verify and install +validate_downloads () { local i=0 - ${UNSAFE} || for pkg_file in ${outputs}; do + ${UNSAFE} || for pkg_file in $@; do ${QUIET} || hbar -T "${LARGE_CIRCLE} validating downloads..." $i $# @@ -131,6 +146,8 @@ download_packages () { install $@ } +# get and install requested packages +# get () { local requested=$@ local missing="" already="" install="" update="" urls="" @@ -194,23 +211,45 @@ get () { } } +# just fetch the xipkg files of requested packages +# fetch () { - local packages=$@ local outputs="" - local total_download=0 - for package in $packages; do - if package_exists $package; then + for package in $@; do + package_exists $package && { set -- $(get_package_download_info $package) - size=$3 - total_download=$((total_download+size)) - - local output="${package}.xipkg" - download_package $package $output - outputs="$outputs $output" - fi + total_download=$((total_download+$3)) + outputs="$outputs ${package}.xipkg" + } done - wait_for_download $total_download ${outputs} + fetch_serial $total_download $outputs +} + +# fetch package files in serial +# +# total_download: total number of bytes to download +# outputs: list of package files to output to +# +fetch_serial () { + wait_for_download $@ & + shift + for output in $@; do + download_package $(basename ${output%.*} | cut -d. -f2) $output + done } +# fetch package files in parallel +# +# total_download: total number of bytes to download +# outputs: list of package files to output to +# +fetch_parallel () { + local total_download=$1 + shift + for output in $@; do + download_package $(basename ${output%.*} | cut -d. -f2) $output & + done + wait_for_download total_download $@ & +} diff --git a/src/install.sh b/src/install.sh index a251820..8631251 100644 --- a/src/install.sh +++ b/src/install.sh @@ -1,7 +1,7 @@ #!/bin/sh extract () { - tar -h -p --no-overwrite-dir -vvxf $1 -C ${SYSROOT} 2>/dev/null | grep ^- | tr -s " " | cut -d" " -f6 | cut -c2- + tar -h --keep-old-files -p -vvxf $1 -C ${SYSROOT} 2>${LOG_FILE} | grep ^- | tr -s " " | cut -d" " -f6 | cut -c2- } install_package () { @@ -17,32 +17,28 @@ install_package () { set -- $(md5sum $pkg_file) local package_checksum=$1 if [ ! -f $checksum ] || [ "$(cat $checksum)" != "$package_checksum" ]; then - mkdir -p "$installed_dir" - [ -f $files ] && mv $files $files.old + [ ! -d $installed_dir ] && mkdir -p "$installed_dir" + + [ -f "$files" ] && { + for file in $(cat $files); do + rm -f ${SYSROOT}$file + done + rm $files + } + ${VERBOSE} && printf "${BLACK}Extracting $name...\n" extract $pkg_file > $files [ -f $info_file ] && cp $info_file $info - echo $package_checksum > $checksum - - - if [ -f "$files.old" ]; then - for file in $(diff $files $files.old | grep ^\> | cut -d' ' -f2); do - rm -f ${SYSROOT}$file - done - rm $files.old - fi return 0 - else - ${VERBOSE} && printf "${BLACK}Skipping $name; already installed...\n" - return 1 fi + ${VERBOSE} && printf "${BLACK}Skipping $name; already installed...\n" + return 1 } get_package_filecount() { - local info=$(get_package_download_info $1) - set -- $info + set -- $(get_package_download_info $1) echo $4 } diff --git a/src/remove.sh b/src/remove.sh index fcff458..56b6a42 100644 --- a/src/remove.sh +++ b/src/remove.sh @@ -49,11 +49,10 @@ remove () { clean () { set -- $(du -sh ${CACHE_DIR}) - - if prompt_question "${LIGHT_RED}Remove ${RED}$1${LIGHT_RED} of cached files?"; then + prompt_question "${LIGHT_RED}Remove ${RED}$1${LIGHT_RED} of cached files?" && { rm -rf ${CACHE_DIR}/* ${QUIET} || printf "${GREEN}Cleared package cache!\n" - else + } || { ${QUIET} || printf "${LIGHT_BLACK}Action cancled by user\n" - fi + } } diff --git a/src/util.sh b/src/util.sh index 501da96..55af05e 100644 --- a/src/util.sh +++ b/src/util.sh @@ -37,7 +37,11 @@ wait_for_download () { while [ "$downloaded" -lt "$total_download" ]; do downloaded=0 for output in $@; do - size=$(stat -t $output | cut -d" " -f2) + [ -f $output ] && { + size=$(stat -t $output | cut -d" " -f2) + } || { + size=0 + } downloaded=$((downloaded+size)) done diff --git a/src/xi.sh b/src/xi.sh index 9bb6bbf..ae53795 100755 --- a/src/xi.sh +++ b/src/xi.sh @@ -64,6 +64,7 @@ Available Commands: EOF } + [ -z "${LIBDIR}" ] && LIBDIR=/usr/lib/xipkg [ -f ${LIBDIR}/VERSION ] && VERSION=$(cat ${LIBDIR}/VERSION) || VERSION= @@ -128,6 +129,12 @@ if [ "$#" = "0" ]; then . ${LIBDIR}/stats.sh show_xipkg_stats else + # showing stats doesn't require root, so we can only check when we are here + [ ! "$EUID" == 0 ] && { + printf "${RED}Please run as root!\n" + exit 1 + } + # todo check for permissions when we need them and ask them per request case "$1" in "sync") sync -- cgit v1.2.1