M usr/sbin/cast => usr/sbin/cast +2 -0
@@ 574,6 574,8 @@ function pass_four() {
message "Can't find spell version for some reason, is $SPELL a spell?"
else
can_resurrect $SPELL $VERSION &> /dev/null &&
+ #TODO: in the end, check if this call is redundant
+ # maybe also ask the user if they want to resurrect an older version
! does_spell_need_update $SPELL &> /dev/null &&
do_resurrect=yes
fi
M usr/sbin/resurrect => usr/sbin/resurrect +7 -2
@@ 55,7 55,7 @@ function do_resurrect() {
# use the version for only one spell in case more were specified (illegal)
unset USE_VERSION
- find_cache "$INSTALL_CACHE/$spell-$requested_version-$HOST" cache
+ find_cache "$INSTALL_CACHE/$spell-$requested_version-$HOST" cache single $SPELL
if [[ ! -f $cache ]]; then
error_message "$error_base no cache for version $requested_version" \
"was found.$DEFAULT_COLOR"
@@ 204,9 204,14 @@ function is_resurrectable() {
local spell=$1
local msg_base="$SPELL_COLOR$spell$DEFAULT_COLOR cannot be resurrected because"
- if ! can_resurrect $spell "*" > /dev/null; then
+ if ! can_resurrect $spell "*" simple > /dev/null; then
message "$msg_base no cache was found!"
return 1
+ else
+ if ! can_resurrect $spell "*"; then
+ message "$msg_base the available caches are too old!"
+ return 1
+ fi
fi
if spell_held $spell; then
message "$msg_base it is held!"
M var/lib/sorcery/modules/libresurrect => var/lib/sorcery/modules/libresurrect +63 -6
@@ 14,15 14,72 @@
## @param spellname
## determines if a particular version of a spell can be resurrected
#---------------------------------------------------------------------
-function can_resurrect() {
+function can_resurrect() { (
debug "libresurrect" "can_resurrect - $*"
local SPELL=$1
local VERSION=$2
+ local mode=${3:-strict}
+ local caches cache
+ local rc=1
+
+ find_cache "$INSTALL_CACHE/$SPELL-$VERSION-$HOST" caches all $SPELL || return 1
+ [[ $mode == simple ]] && return 0
+
+ codex_set_current_spell_quick $(codex_find_spell_by_name $SPELL)
+
+ # if there is more than one, check all, but one good cache is enough
+ for cache in $caches; do
+ # check if the patchlevels match
+ local label=$(tar --test-label --file "$cache" 2>/dev/null)
+ if [[ -z $label ]]; then
+ # no label - do file-based lookup from the cache
+ local tablet_path=var/state/sorcery/tablet
+ # get the spellname/date part of the path
+ local tmp=$(tar tOfOO "$cache" 2>&1 $tablet_path | sed -n "1 s,$tablet_path/,,p; q")
+
+ local version patchlevel security_patch updated
+ version=$(tar fOx "$cache" 2>&1 $tablet_path/$tmp/version)
+ patchlevel=$(tar fOx "$cache" 2>&1 $tablet_path/$tmp/patchlevel)
+ security_patch=$(tar fOx "$cache" 2>&1 $tablet_path/$tmp/security_patch)
+ updated=$(tar fOOx "$cache" 2>&1 $tablet_path/$tmp/updated)
+
+ if [[ $VERSION == "*" ]] || [[ ${version:-0} == $VERSION ]] &&
+#FIXME
+#some callers may not care if the patchlevels don't match
+#so think about adding more modes
+#/FIXME
+ [[ $patchlevel == ${PATCHLEVEL:-0} ]] &&
+ [[ $security_patch == ${SECURITY_PATCH:-0} ]] &&
+ [[ ${updated:-0} == ${UPDATED:-0} ]]; then
+ rc=0
+ break
+ else
+ rc=1
+ continue
+ fi
+ else
+ local factors="$SPELL ${VERSION:-0} ${PATCHLEVEL:-0} ${SECURITY_PATCH:-0} ${UPDATED:-0}"
+ if [[ $label == $factors ]]; then
+ rc=0
+ break
+ else
+ rc=1
+ continue
+ fi
+ fi
- find_cache "$INSTALL_CACHE/$SPELL-$VERSION-$HOST" || return 1
- debug "libresurrect" "I am able to resurrect."
- return 0
-}
+ #TODO check if subdependencies are satisfied
+ #TODO HERE?: don't resurrect if a cast_self trigger is known
+
+ done
+
+ if [[ $rc == 0 ]]; then
+ debug "libresurrect" "I am able to resurrect."
+ fi
+ #codex_clear_current_spell #instead we're in a subshell to prevent any kind of leakage
+
+ return $rc
+) }
#------------------------------------------------------------------------
## @param spell
@@ 83,7 140,7 @@ function resurrect_spell() { (
# 1) if no cache file exists fail
if [[ -z $CACHE_COMP ]]; then
- CACHE_COMP=$(can_resurrect $SPELL $VERSION) || {
+ find_cache "$INSTALL_CACHE/$SPELL-$VERSION-$HOST" CACHE_COMP single $SPELL || {
message "No cache file could be found"
return 1
}
M var/lib/sorcery/modules/libtrack => var/lib/sorcery/modules/libtrack +52 -10
@@ 357,23 357,65 @@ function construct_cache_name() {
function find_cache() {
debug "libtrack" "$FUNCNAME $@"
local filename=$1
+ local upvar=$2
+ local mode=${3:-single}
+ local spell=$4
local real_name
- if [[ -f $filename ]]; then
- real_name=$filename
+ # always find all the caches then check if they are really of the right spell;
+ # this avoids problems like wine matching in wine-gecko, since the cache
+ # filenames use the dash as a field separator and are thus unreliable
+ local basename _caches
+ smgl_basename "$filename" basename
+ _caches=$(find $INSTALL_CACHE -type f -name "$basename*" | sort -V)
+ if [[ -n $spell ]]; then # no point in checking if we have nothing to compare against
+ local _cache good_caches
+ for _cache in $_caches; do
+ local label=( $(tar --test-label --file $_cache 2>/dev/null) )
+ if [[ ${label[0]} != $spell ]]; then
+ continue
+ else
+ good_caches="$_cache $good_caches"
+ fi
+ done
+
+ if [[ -z $good_caches ]]; then
+ debug "libtrack" "$FUNCNAME found no good cache labels for: $filename"
+ return 1
+ fi
+
+ # any cache of the good_caches will do
+ if [[ $mode == all ]]; then
+ real_name="$good_caches"
+ else
+ # use the first if more were found
+ # usually the most recent version one, due to the sort call on _caches
+ read real_name < <(cut -d" " -f1 <<< "$good_caches")
+ fi
else
- # use the first if more were found
- local basename
- smgl_basename "$filename" basename
- read real_name < <(find $INSTALL_CACHE -type f -name "$basename*")
+ # old dumb mode
+ # only alter calls this function without the spell argument
+ debug "libtrack" "$FUNCNAME with no spell argument: $filename"
+
+ if [[ -f $filename ]]; then
+ real_name=$filename
+ else
+ if [[ $mode == all ]]; then
+ real_name=$_caches
+ else
+ # use the first if more were found
+ real_name=$(tail -n1 <<< "$_caches")
+ fi
+ fi
+ [[ -z $real_name ]] && return 1
fi
- [[ -z $real_name ]] && return 1
+
debug "libtrack" "$FUNCNAME found $real_name"
- if [[ -z $2 ]]; then
- echo $real_name
+ if [[ -z $upvar ]]; then
+ echo "$real_name"
else
- upvar $2 "$real_name"
+ upvar $upvar "$real_name"
fi
return 0
}