mirror of
https://codeberg.org/kiss-community/kiss
synced 2024-12-25 00:20:05 -07:00
kiss: unique temporary files
All temporary files now have unique names and reuse of the same file for multiple purposes has been removed. This prevents issues where a failed write to a log file used in multiple places can cause prior data to be read elsewhere in the package manager.
This commit is contained in:
parent
e853e1accc
commit
9895a14e83
105
kiss
105
kiss
@ -44,6 +44,29 @@ contains() {
|
|||||||
case " $1 " in *" $2 "*) return 0; esac; return 1
|
case " $1 " in *" $2 "*) return 0; esac; return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmp_file() {
|
||||||
|
# Create a uniquely named temporary file and store its absolute path
|
||||||
|
# in a variable (_tmp_file).
|
||||||
|
#
|
||||||
|
# To prevent subshell usage and to handle cases where multiple files
|
||||||
|
# are needed, this saves the last two temporary files to variables
|
||||||
|
# for access by the caller (allowing 3 files at once).
|
||||||
|
_tmp_file_pre_pre=$_tmp_file_pre
|
||||||
|
_tmp_file_pre=$_tmp_file
|
||||||
|
_tmp_file=$mak_dir/.$pid-$1-$2
|
||||||
|
|
||||||
|
: > "$_tmp_file" ||
|
||||||
|
die "$1" "Failed to create temporary file"
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp_file_copy() {
|
||||||
|
# Create a uniquely named temporary file and make a duplicate of
|
||||||
|
# the file in '$3' if it exists.
|
||||||
|
tmp_file "$1" "$2"
|
||||||
|
|
||||||
|
! [ -f "$3" ] || cp -f "$3" "$_tmp_file"
|
||||||
|
}
|
||||||
|
|
||||||
prompt() {
|
prompt() {
|
||||||
[ "$1" ] && log "$1"
|
[ "$1" ] && log "$1"
|
||||||
|
|
||||||
@ -925,8 +948,10 @@ pkg_verify() {
|
|||||||
set -- "$@" "$chk"
|
set -- "$@" "$chk"
|
||||||
done 2>/dev/null < "$repo_dir/checksums"
|
done 2>/dev/null < "$repo_dir/checksums"
|
||||||
|
|
||||||
|
tmp_file "$1" verify
|
||||||
|
|
||||||
# Generate a new set of checksums to compare against.
|
# Generate a new set of checksums to compare against.
|
||||||
pkg_checksums "$1" > "$mak_dir/v"
|
pkg_checksums "$1" > "$_tmp_file"
|
||||||
|
|
||||||
# Check that the first column (separated by whitespace) match in both
|
# Check that the first column (separated by whitespace) match in both
|
||||||
# checksum files. If any part of either file differs, mismatch. Abort.
|
# checksum files. If any part of either file differs, mismatch. Abort.
|
||||||
@ -938,13 +963,16 @@ pkg_verify() {
|
|||||||
|
|
||||||
*) die "${repo_dir##*/}" "Checksum mismatch"
|
*) die "${repo_dir##*/}" "Checksum mismatch"
|
||||||
esac
|
esac
|
||||||
done < "$mak_dir/v"
|
done < "$_tmp_file"
|
||||||
}
|
}
|
||||||
|
|
||||||
pkg_conflicts() {
|
pkg_conflicts() {
|
||||||
# Check to see if a package conflicts with another.
|
# Check to see if a package conflicts with another.
|
||||||
log "$1" "Checking for package conflicts"
|
log "$1" "Checking for package conflicts"
|
||||||
|
|
||||||
|
tmp_file "$1" manifest-files
|
||||||
|
tmp_file "$1" found-conflicts
|
||||||
|
|
||||||
# Filter the tarball's manifest and select only files. Resolve all
|
# Filter the tarball's manifest and select only files. Resolve all
|
||||||
# symlinks in file paths as well.
|
# symlinks in file paths as well.
|
||||||
while read -r file; do
|
while read -r file; do
|
||||||
@ -961,7 +989,7 @@ pkg_conflicts() {
|
|||||||
# Print the file with all symlinks in its path
|
# Print the file with all symlinks in its path
|
||||||
# resolved to their real locations.
|
# resolved to their real locations.
|
||||||
printf '%s\n' "${PWD#"$KISS_ROOT"}/${file##*/}"
|
printf '%s\n' "${PWD#"$KISS_ROOT"}/${file##*/}"
|
||||||
done < "$tar_dir/$1/$pkg_db/$1/manifest" > "$mak_dir/cf_m"
|
done < "$tar_dir/$1/$pkg_db/$1/manifest" > "$_tmp_file_pre"
|
||||||
|
|
||||||
cd "$tar_dir/$1"
|
cd "$tar_dir/$1"
|
||||||
|
|
||||||
@ -989,16 +1017,16 @@ pkg_conflicts() {
|
|||||||
# Store the list of found conflicts in a file as we'll be using the
|
# Store the list of found conflicts in a file as we'll be using the
|
||||||
# information multiple times. Storing things in the cache dir allows
|
# information multiple times. Storing things in the cache dir allows
|
||||||
# us to be lazy as they'll be automatically removed on script end.
|
# us to be lazy as they'll be automatically removed on script end.
|
||||||
grep -Fxf "$mak_dir/cf_m" -- "$@" 2>/dev/null > "$mak_dir/cf" || :
|
grep -Fxf "$_tmp_file_pre" -- "$@" 2>/dev/null > "$_tmp_file" || :
|
||||||
|
|
||||||
# Enable alternatives automatically if it is safe to do so.
|
# Enable alternatives automatically if it is safe to do so.
|
||||||
# This checks to see that the package that is about to be installed
|
# This checks to see that the package that is about to be installed
|
||||||
# doesn't overwrite anything it shouldn't in '/var/db/kiss/installed'.
|
# doesn't overwrite anything it shouldn't in '/var/db/kiss/installed'.
|
||||||
grep -q ":/var/db/kiss/installed/" "$mak_dir/cf" || choice_auto=1
|
grep -q ":/var/db/kiss/installed/" "$_tmp_file" || choice_auto=1
|
||||||
|
|
||||||
if [ "$KISS_CHOICE" != 0 ] &&
|
if [ "$KISS_CHOICE" != 0 ] &&
|
||||||
[ "$choice_auto" = 1 ] &&
|
[ "$choice_auto" = 1 ] &&
|
||||||
[ -s "$mak_dir/cf" ]; then
|
[ -s "$_tmp_file" ]; then
|
||||||
# This is a novel way of offering an "alternatives" system.
|
# This is a novel way of offering an "alternatives" system.
|
||||||
# It is entirely dynamic and all "choices" are created and
|
# It is entirely dynamic and all "choices" are created and
|
||||||
# destroyed on the fly.
|
# destroyed on the fly.
|
||||||
@ -1042,7 +1070,7 @@ pkg_conflicts() {
|
|||||||
log "this must be fixed in $p_name. Contact the maintainer"
|
log "this must be fixed in $p_name. Contact the maintainer"
|
||||||
die "by finding their details via 'kiss-maintainer'" "" "!>"
|
die "by finding their details via 'kiss-maintainer'" "" "!>"
|
||||||
}
|
}
|
||||||
done < "$mak_dir/cf"
|
done < "$_tmp_file"
|
||||||
|
|
||||||
log "$p_name" "Converted all conflicts to choices (kiss a)"
|
log "$p_name" "Converted all conflicts to choices (kiss a)"
|
||||||
|
|
||||||
@ -1050,7 +1078,7 @@ pkg_conflicts() {
|
|||||||
# to its new spot (and name) in the choices directory.
|
# to its new spot (and name) in the choices directory.
|
||||||
pkg_manifest "$p_name" "$tar_dir" 2>/dev/null
|
pkg_manifest "$p_name" "$tar_dir" 2>/dev/null
|
||||||
|
|
||||||
elif [ -s "$mak_dir/cf" ]; then
|
elif [ -s "$_tmp_file" ]; then
|
||||||
log "Package '$p_name' conflicts with another package" "" "!>"
|
log "Package '$p_name' conflicts with another package" "" "!>"
|
||||||
log "Run 'KISS_CHOICE=1 kiss i $p_name' to add conflicts" "" "!>"
|
log "Run 'KISS_CHOICE=1 kiss i $p_name' to add conflicts" "" "!>"
|
||||||
die "as alternatives." "" "!>"
|
die "as alternatives." "" "!>"
|
||||||
@ -1082,6 +1110,7 @@ pkg_swap() {
|
|||||||
[ "$pkg_owns" ] || die "File '$2' exists on filesystem but isn't owned"
|
[ "$pkg_owns" ] || die "File '$2' exists on filesystem but isn't owned"
|
||||||
|
|
||||||
log "Swapping '$2' from '$pkg_owns' to '$1'"
|
log "Swapping '$2' from '$pkg_owns' to '$1'"
|
||||||
|
tmp_file "$pkg_owns" from-alt
|
||||||
|
|
||||||
# Convert the current owner to an alternative and rewrite its manifest
|
# Convert the current owner to an alternative and rewrite its manifest
|
||||||
# file to reflect this.
|
# file to reflect this.
|
||||||
@ -1096,15 +1125,17 @@ pkg_swap() {
|
|||||||
"$2") printf '%s\n' "${PWD#"$KISS_ROOT"}/$pkg_owns>${alt#*>}" ;;
|
"$2") printf '%s\n' "${PWD#"$KISS_ROOT"}/$pkg_owns>${alt#*>}" ;;
|
||||||
*) printf '%s\n' "$line" ;;
|
*) printf '%s\n' "$line" ;;
|
||||||
esac
|
esac
|
||||||
done < "../installed/$pkg_owns/manifest" | sort -r > "$mak_dir/.$1"
|
done < "../installed/$pkg_owns/manifest" | sort -r > "$_tmp_file"
|
||||||
|
|
||||||
mv -f "$mak_dir/.$1" "../installed/$pkg_owns/manifest"
|
mv -f "$_tmp_file" "../installed/$pkg_owns/manifest"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Convert the desired alternative to a real file and rewrite the manifest
|
# Convert the desired alternative to a real file and rewrite the manifest
|
||||||
# file to reflect this. The reverse of above.
|
# file to reflect this. The reverse of above.
|
||||||
mv -f "$alt" "$KISS_ROOT/$2"
|
mv -f "$alt" "$KISS_ROOT/$2"
|
||||||
|
|
||||||
|
tmp_file "$pkg_owns" to-alt
|
||||||
|
|
||||||
# Replace the matching line in the manifest with the desired replacement.
|
# Replace the matching line in the manifest with the desired replacement.
|
||||||
# This used to be a 'sed' call which turned out to be a little error-prone
|
# This used to be a 'sed' call which turned out to be a little error-prone
|
||||||
# in some cases. This new method is a tad slower but ensures we never wipe
|
# in some cases. This new method is a tad slower but ensures we never wipe
|
||||||
@ -1114,9 +1145,9 @@ pkg_swap() {
|
|||||||
"${PWD#"$KISS_ROOT"}/$alt") printf '%s\n' "$2" ;;
|
"${PWD#"$KISS_ROOT"}/$alt") printf '%s\n' "$2" ;;
|
||||||
*) printf '%s\n' "$line" ;;
|
*) printf '%s\n' "$line" ;;
|
||||||
esac
|
esac
|
||||||
done < "../installed/$1/manifest" | sort -r > "$mak_dir/.$1"
|
done < "../installed/$1/manifest" | sort -r > "$_tmp_file"
|
||||||
|
|
||||||
mv -f "$mak_dir/.$1" "../installed/$1/manifest"
|
mv -f "$_tmp_file" "../installed/$1/manifest"
|
||||||
}
|
}
|
||||||
|
|
||||||
file_rwx() {
|
file_rwx() {
|
||||||
@ -1196,7 +1227,7 @@ pkg_remove_files() {
|
|||||||
while read -r file; do
|
while read -r file; do
|
||||||
case $file in /etc/?*[!/])
|
case $file in /etc/?*[!/])
|
||||||
sh256 "$KISS_ROOT/$file" >/dev/null
|
sh256 "$KISS_ROOT/$file" >/dev/null
|
||||||
sum_old=$(grep -F "${hash:-null}" "$mak_dir/c")
|
sum_old=$(grep -F "${hash:-null}" "$1")
|
||||||
|
|
||||||
[ "${hash:-null}" = "$sum_old" ] || {
|
[ "${hash:-null}" = "$sum_old" ] || {
|
||||||
printf 'Skipping %s (modified)\n' "$file"
|
printf 'Skipping %s (modified)\n' "$file"
|
||||||
@ -1222,6 +1253,9 @@ pkg_remove_files() {
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# First argument needs to be dropped.
|
||||||
|
shift
|
||||||
|
|
||||||
# Remove all broken directory symlinks.
|
# Remove all broken directory symlinks.
|
||||||
for sym do
|
for sym do
|
||||||
[ -e "$sym" ] || rm -f "$sym"
|
[ -e "$sym" ] || rm -f "$sym"
|
||||||
@ -1229,9 +1263,9 @@ pkg_remove_files() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pkg_etc() (
|
pkg_etc() (
|
||||||
[ -d "$tar_dir/$pkg_name/etc" ] || return 0
|
[ -d "$tar_dir/$1/etc" ] || return 0
|
||||||
|
|
||||||
cd "$tar_dir/$pkg_name"
|
cd "$tar_dir/$1"
|
||||||
|
|
||||||
# Create all directories beforehand.
|
# Create all directories beforehand.
|
||||||
find etc -type d | while read -r dir; do
|
find etc -type d | while read -r dir; do
|
||||||
@ -1244,9 +1278,9 @@ pkg_etc() (
|
|||||||
|
|
||||||
{ sh256 "$file"; sum_new=$hash
|
{ sh256 "$file"; sum_new=$hash
|
||||||
sh256 "$KISS_ROOT/$file"; sum_sys=$hash
|
sh256 "$KISS_ROOT/$file"; sum_sys=$hash
|
||||||
sum_old=$(awk "NR == $i" "$mak_dir/c"); } >/dev/null 2>&1 || :
|
sum_old=$(awk "NR == $i" "$2"); } >/dev/null 2>&1 || :
|
||||||
|
|
||||||
log "$pkg_name" "Doing 3-way handshake for $file"
|
log "$1" "Doing 3-way handshake for $file"
|
||||||
printf '%s\n' "Previous: ${sum_old:-null}"
|
printf '%s\n' "Previous: ${sum_old:-null}"
|
||||||
printf '%s\n' "System: ${sum_sys:-null}"
|
printf '%s\n' "System: ${sum_sys:-null}"
|
||||||
printf '%s\n' "New: ${sum_new:-null}"
|
printf '%s\n' "New: ${sum_new:-null}"
|
||||||
@ -1272,7 +1306,7 @@ pkg_etc() (
|
|||||||
|
|
||||||
# All other cases.
|
# All other cases.
|
||||||
*)
|
*)
|
||||||
war "$pkg_name" "saving /$file as /$file.new"
|
war "$1" "saving /$file as /$file.new"
|
||||||
new=.new
|
new=.new
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -1317,11 +1351,11 @@ pkg_remove() {
|
|||||||
run_hook_pkg pre-remove "$1"
|
run_hook_pkg pre-remove "$1"
|
||||||
run_hook pre-remove "$1" "$sys_db/$1"
|
run_hook pre-remove "$1" "$sys_db/$1"
|
||||||
|
|
||||||
# Make a backup of the etcsums file (if it exists).
|
# Make a backup of any etcsums if they exist.
|
||||||
cp -f "$sys_db/$1/etcsums" "$mak_dir/c" 2>/dev/null || : > "$mak_dir/c"
|
tmp_file_copy "$pkg_name" etcsums-copy "$sys_db/$pkg_name/etcsums"
|
||||||
|
|
||||||
log "$1" "Removing package"
|
log "$1" "Removing package"
|
||||||
pkg_remove_files < "$sys_db/$1/manifest"
|
pkg_remove_files "$_tmp_file" < "$sys_db/$1/manifest"
|
||||||
|
|
||||||
# Reset 'trap' to its original value. Removal is done so
|
# Reset 'trap' to its original value. Removal is done so
|
||||||
# we no longer need to block 'Ctrl+C'.
|
# we no longer need to block 'Ctrl+C'.
|
||||||
@ -1431,23 +1465,26 @@ pkg_install() {
|
|||||||
|
|
||||||
log "$pkg_name" "Installing package (${tar_file##*/})"
|
log "$pkg_name" "Installing package (${tar_file##*/})"
|
||||||
|
|
||||||
|
# Make a backup of any etcsums if they exist.
|
||||||
|
tmp_file_copy "$pkg_name" etcsums-copy "$sys_db/$pkg_name/etcsums"
|
||||||
|
_etc_sums=$_tmp_file
|
||||||
|
|
||||||
# If the package is already installed (and this is an upgrade) make a
|
# If the package is already installed (and this is an upgrade) make a
|
||||||
# backup of the manifest and etcsums files.
|
# backup of the manifest and etcsums files.
|
||||||
cp -f "$sys_db/$pkg_name/manifest" "$mak_dir/m" 2>/dev/null ||
|
tmp_file_copy "$pkg_name" manifest-copy "$sys_db/$pkg_name/manifest"
|
||||||
: > "$mak_dir/m"
|
tmp_file "$pkg_name" manifest-diff
|
||||||
cp -f "$sys_db/$pkg_name/etcsums" "$mak_dir/c" 2>/dev/null ||
|
|
||||||
: > "$mak_dir/c"
|
|
||||||
|
|
||||||
tar_man=$tar_dir/$pkg_name/$pkg_db/$pkg_name/manifest
|
tar_man=$tar_dir/$pkg_name/$pkg_db/$pkg_name/manifest
|
||||||
|
|
||||||
|
# Generate a list of files which exist in the currently installed manifest
|
||||||
|
# but not in the newer (to be installed) manifest.
|
||||||
|
grep -vFxf "$tar_man" "$_tmp_file_pre" > "$_tmp_file" 2>/dev/null ||:
|
||||||
|
|
||||||
# Reverse the manifest file so that we start shallow and go deeper as we
|
# Reverse the manifest file so that we start shallow and go deeper as we
|
||||||
# iterate over each item. This is needed so that directories are created
|
# iterate over each item. This is needed so that directories are created
|
||||||
# going down the tree.
|
# going down the tree.
|
||||||
sort "$tar_man" > "$mak_dir/if"
|
tmp_file "$pkg_name" manifest-reverse
|
||||||
|
sort "$tar_man" > "$_tmp_file"
|
||||||
# Generate a list of files which exist in the currently installed manifest
|
|
||||||
# but not in the newer (to be installed) manifest.
|
|
||||||
grep -vFxf "$tar_man" "$mak_dir/m" > "$mak_dir/rm" 2>/dev/null ||:
|
|
||||||
|
|
||||||
# Block being able to abort the script with Ctrl+C during installation.
|
# Block being able to abort the script with Ctrl+C during installation.
|
||||||
# Removes all risk of the user aborting a package installation leaving
|
# Removes all risk of the user aborting a package installation leaving
|
||||||
@ -1456,7 +1493,7 @@ pkg_install() {
|
|||||||
|
|
||||||
if
|
if
|
||||||
# Install the package's files by iterating over its manifest.
|
# Install the package's files by iterating over its manifest.
|
||||||
pkg_install_files -z "$tar_dir/$pkg_name" < "$mak_dir/if" &&
|
pkg_install_files -z "$tar_dir/$pkg_name" < "$_tmp_file" &&
|
||||||
|
|
||||||
# Handle /etc/ files in a special way (via a 3-way checksum) to
|
# Handle /etc/ files in a special way (via a 3-way checksum) to
|
||||||
# determine how these files should be installed. Do we overwrite the
|
# determine how these files should be installed. Do we overwrite the
|
||||||
@ -1465,16 +1502,16 @@ pkg_install() {
|
|||||||
#
|
#
|
||||||
# This is more or less similar to Arch Linux's Pacman with the user
|
# This is more or less similar to Arch Linux's Pacman with the user
|
||||||
# manually handling the .new files when and if they appear.
|
# manually handling the .new files when and if they appear.
|
||||||
pkg_etc &&
|
pkg_etc "$pkg_name" "$_etc_sums" &&
|
||||||
|
|
||||||
# This is the aforementioned step removing any files from the old
|
# This is the aforementioned step removing any files from the old
|
||||||
# version of the package if the installation is an update. Each file
|
# version of the package if the installation is an update. Each file
|
||||||
# type has to be specially handled to ensure no system breakage occurs.
|
# type has to be specially handled to ensure no system breakage occurs.
|
||||||
pkg_remove_files < "$mak_dir/rm" &&
|
pkg_remove_files "$_etc_sums" < "$_tmp_file_pre" &&
|
||||||
|
|
||||||
# Install the package's files a second time to fix any mess caused by
|
# Install the package's files a second time to fix any mess caused by
|
||||||
# the above removal of the previous version of the package.
|
# the above removal of the previous version of the package.
|
||||||
pkg_install_files -e "$tar_dir/$pkg_name" < "$mak_dir/if"
|
pkg_install_files -e "$tar_dir/$pkg_name" < "$_tmp_file"
|
||||||
|
|
||||||
then
|
then
|
||||||
# Reset 'trap' to its original value. Installation is done so we no longer
|
# Reset 'trap' to its original value. Installation is done so we no longer
|
||||||
|
Loading…
Reference in New Issue
Block a user