Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- SIZE=( )
- FILES=( )
- lastpkg=""
- oIFS="$IFS"
- function packageDisplay
- {
- for (( i=0; i < ${#packages[@]}; i++ ))
- do
- echo "${SIZE[i]} ${packages[i]} ${FILES[i]} $i"
- done
- }
- if [ "$1" == "--clean" ]
- then
- rm -f "/tmp/.pkgscan_cache"
- fi
- if [ -f "/tmp/.pkgscan_cache" ]
- then
- echo "Loading from cache..."
- IFS=$'\n'
- tmp=( $( cat /tmp/.pkgscan_cache ) )
- IFS="${oIFS}"
- for line in "${tmp[@]}"
- do
- size="${line%% *}"
- line="${line#* }"
- name="${line%% *}"
- line="${line#* }"
- files="${line%% *}"
- i="${line#* }"
- packages[i]="${name}"
- FILES[i]="${files}"
- SIZE[i]="${size}"
- done
- else
- echo -n "Building package list..."
- packages=( $( dpkg -l | sed '1,5d' | awk '{print $2}' ) )
- echo "done"
- pkgMax="${#packages[@]}"
- echo -n "Scanning... [ "
- for (( i=0; i < ${#packages[@]}; i++ ))
- do
- pkgNum=$(( i + 1 ))
- echo -ne "${pkgNum}/${pkgMax}] ${lastpkg//?/ }\E[${#lastpkg}D"
- echo -ne "${packages[i]}"
- echo -ne "\E[$(( 3 + ${#pkgNum} + ${#pkgMax} + ${#packages[i]} ))D"
- lastpkg="${packages[$i]}"
- IFS=$'\n'
- files=(
- $(
- ls -aALsd $( dpkg -L "${packages[$i]}" ) 2>&- | {
- totalsize=0
- IFS="$oIFS"
- while read size file
- do
- if [[ $file == /usr/* ]] \
- && [ -f "$file" ]
- then
- echo "${file}"
- (( totalsize += $size ))
- fi
- done
- echo "$totalsize"
- }
- )
- )
- IFS="${oIFS}"
- (( totalfiles = ${#files[@]} - 1 ))
- SIZE[i]="${files[totalfiles]}"
- unset files[totalfiles]
- FILES[$i]="$totalfiles"
- done
- packageDisplay > /tmp/.pkgscan_cache
- echo
- fi
- echo -n "Sorting..."
- IFS=$'\n'
- sorted=(
- $(
- packageDisplay | sort -r -n
- )
- )
- echo "done"
- echo -e "\nReady.\n"
- function resolve_paths
- {
- file="${1}"
- path="${file%/*}"
- name="${file##*/}"
- package="${2}"
- target="/opt/relocated/${package}/${path}"
- temp="${file}.relocate_tmp"
- while [ -e "${temp}" ]
- do
- temp="${temp}.$RANDOM"
- done
- }
- function undo
- {
- resolve_paths "${@}"
- echo -n "${file}: "
- mkdir -p "${path}"
- echo -n "copy..."
- cp "${target}/${name}" "${temp}"
- if ! cmp "${temp}" "${target}/${name}"
- then
- echo "FATAL ERROR: copy is not identical"
- exit 1
- fi
- if mv "${temp}" "${file}"
- then
- echo "done"
- else
- echo "FATAL ERROR: switch failed."
- exit 1
- fi
- }
- function relocate
- {
- resolve_paths "${@}"
- echo -n "${file}: "
- mkdir -p "${target}"
- echo -n "copy..."
- cp "${file}" "${target}/${name}"
- if ! cmp "${file}" "${target}/${name}"
- then
- echo "FATAL ERROR: copy is not identical"
- exit 1
- fi
- echo -n "link..."
- ln -nsf "${target}/${name}" "${temp}"
- if ! cmp "${temp}" "${target}/${name}"
- then
- echo "FATAL ERROR: linked file differs from original"
- exit 1
- fi
- echo -n "switch..."
- if mv "${temp}" "${file}"
- then
- echo "done"
- else
- echo "FATAL ERROR: switch failed."
- exit 1
- fi
- }
- for pkgdata in "${sorted[@]}"
- do
- pkgnum="${pkgdata##* }"
- echo
- echo "Package: ${packages[pkgnum]}"
- echo "Files: ${#FILES[pkgnum]}"
- echo "Size in /usr: ${SIZE[pkgnum]} blocks"
- if [ -d /opt/relocated/${packages[pkgnum]} ]
- then
- echo "Currently archived in /opt"
- echo -n "Type 'undo' to undo: "
- else
- echo -n "Type 'arc' to archive: "
- fi
- read answer
- case $answer in
- 'arc')
- dpkg -L "${packages[pkgnum]}" | while read file
- do
- if [[ $file == /usr/* ]] \
- && [ -f "$file" ]
- then
- relocate "$file" "${packages[pkgnum]}"
- fi
- done
- ;;
- 'undo')
- dpkg -L "${packages[pkgnum]}" | {
- files=0
- while read file
- do
- if [[ $file == /usr/* ]] \
- && [ -f "/opt/relocated/${packages[pkgnum]}/$file" ]
- then
- (( files++ ))
- if ! undo "$file" "${packages[pkgnum]}"
- then
- echo "Fatal error: Failed to undo relocation of $file"
- exit 1
- fi
- fi
- done
- if (( files > 0 ))
- then
- echo "Cleaning up..."
- rm -rf "/opt/relocated/${packages[pkgnum]}"
- else
- echo "Not cleaning up: Suspiciously, no files were unrelocated"
- fi
- }
- ;;
- esac
- done
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement