Advertisement
Guest User

ccooke

a guest
Oct 24th, 2009
1,077
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 5.10 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. SIZE=( )
  4. FILES=( )
  5. lastpkg=""
  6. oIFS="$IFS"
  7.  
  8. function packageDisplay
  9. {
  10.     for (( i=0; i < ${#packages[@]}; i++ ))
  11.     do
  12.         echo "${SIZE[i]} ${packages[i]} ${FILES[i]} $i"
  13.     done
  14. }
  15.  
  16. if [ "$1" == "--clean" ]
  17. then
  18.     rm -f "/tmp/.pkgscan_cache"
  19. fi
  20.  
  21. if [ -f "/tmp/.pkgscan_cache" ]
  22. then
  23.     echo "Loading from cache..."
  24.  
  25.     IFS=$'\n'
  26.     tmp=( $( cat /tmp/.pkgscan_cache ) )
  27.     IFS="${oIFS}"
  28.     for line in "${tmp[@]}"
  29.     do
  30.         size="${line%% *}"
  31.         line="${line#* }"
  32.         name="${line%% *}"
  33.         line="${line#* }"
  34.         files="${line%% *}"
  35.         i="${line#* }"
  36.        
  37.         packages[i]="${name}"
  38.         FILES[i]="${files}"
  39.         SIZE[i]="${size}"
  40.     done
  41. else
  42.     echo -n "Building package list..."
  43.     packages=( $( dpkg -l | sed '1,5d' | awk '{print $2}' ) )
  44.     echo "done"
  45.  
  46.     pkgMax="${#packages[@]}"
  47.     echo -n "Scanning... [ "
  48.  
  49.     for (( i=0; i < ${#packages[@]}; i++ ))
  50.     do
  51.         pkgNum=$(( i + 1 ))
  52.         echo -ne "${pkgNum}/${pkgMax}] ${lastpkg//?/ }\E[${#lastpkg}D"
  53.         echo -ne "${packages[i]}"
  54.         echo -ne "\E[$(( 3 + ${#pkgNum} + ${#pkgMax} + ${#packages[i]} ))D"
  55.         lastpkg="${packages[$i]}"
  56.  
  57.         IFS=$'\n'
  58.         files=(
  59.             $(
  60.                 ls -aALsd $( dpkg -L "${packages[$i]}" ) 2>&- | {
  61.                     totalsize=0
  62.                     IFS="$oIFS"
  63.                     while read size file
  64.                     do
  65.                         if [[ $file == /usr/* ]] \
  66.                            && [ -f "$file" ]
  67.                         then
  68.                             echo "${file}"
  69.                             (( totalsize += $size ))
  70.                         fi
  71.                     done
  72.  
  73.                     echo "$totalsize"
  74.                 }
  75.             )
  76.         )
  77.         IFS="${oIFS}"
  78.  
  79.         (( totalfiles = ${#files[@]} - 1 ))
  80.         SIZE[i]="${files[totalfiles]}"
  81.         unset files[totalfiles]
  82.  
  83.         FILES[$i]="$totalfiles"
  84.  
  85.     done
  86.  
  87.     packageDisplay > /tmp/.pkgscan_cache
  88.     echo
  89. fi
  90.  
  91. echo -n "Sorting..."
  92.  
  93. IFS=$'\n'
  94. sorted=(
  95.     $(
  96.         packageDisplay | sort -r -n
  97.     )
  98. )
  99. echo "done"
  100.  
  101. echo -e "\nReady.\n"
  102.  
  103. function resolve_paths
  104. {
  105.     file="${1}"
  106.     path="${file%/*}"
  107.     name="${file##*/}"
  108.  
  109.     package="${2}"
  110.  
  111.     target="/opt/relocated/${package}/${path}"
  112.  
  113.     temp="${file}.relocate_tmp"
  114.     while [  -e "${temp}" ]
  115.     do
  116.         temp="${temp}.$RANDOM"
  117.     done
  118. }
  119.  
  120. function undo
  121. {
  122.     resolve_paths "${@}"
  123.  
  124.     echo -n "${file}: "
  125.     mkdir -p "${path}"
  126.     echo -n "copy..."
  127.     cp "${target}/${name}" "${temp}"
  128.     if ! cmp "${temp}" "${target}/${name}"
  129.     then    
  130.         echo "FATAL ERROR: copy is not identical"
  131.         exit 1
  132.     fi
  133.     if mv "${temp}" "${file}"
  134.     then
  135.         echo "done"
  136.     else
  137.         echo "FATAL ERROR: switch failed."
  138.         exit 1
  139.     fi
  140. }
  141.  
  142. function relocate
  143. {
  144.     resolve_paths "${@}"
  145.  
  146.     echo -n "${file}: "
  147.     mkdir -p "${target}"
  148.     echo -n "copy..."
  149.     cp "${file}" "${target}/${name}"
  150.     if ! cmp "${file}" "${target}/${name}"
  151.     then    
  152.         echo "FATAL ERROR: copy is not identical"
  153.         exit 1
  154.     fi
  155.     echo -n "link..."
  156.     ln -nsf "${target}/${name}" "${temp}"
  157.     if ! cmp "${temp}" "${target}/${name}"
  158.     then    
  159.         echo "FATAL ERROR: linked file differs from original"
  160.         exit 1
  161.     fi
  162.     echo -n "switch..."
  163.     if mv "${temp}" "${file}"
  164.     then
  165.         echo "done"
  166.     else
  167.         echo "FATAL ERROR: switch failed."
  168.         exit 1
  169.     fi
  170. }
  171.  
  172. for pkgdata in "${sorted[@]}"
  173. do
  174.     pkgnum="${pkgdata##* }"
  175.     echo
  176.     echo "Package: ${packages[pkgnum]}"
  177.     echo "Files:   ${#FILES[pkgnum]}"
  178.     echo "Size in /usr: ${SIZE[pkgnum]} blocks"
  179.  
  180.     if [ -d /opt/relocated/${packages[pkgnum]} ]
  181.     then
  182.         echo "Currently archived in /opt"
  183.         echo -n "Type 'undo' to undo: "
  184.     else
  185.         echo -n "Type 'arc' to archive: "
  186.     fi
  187.     read answer
  188.  
  189.     case $answer in
  190.     'arc')
  191.         dpkg -L "${packages[pkgnum]}" | while read file
  192.         do
  193.             if [[ $file == /usr/* ]] \
  194.                && [ -f "$file" ]
  195.             then
  196.                 relocate "$file" "${packages[pkgnum]}"
  197.             fi
  198.         done
  199.         ;;
  200.     'undo')
  201.         dpkg -L "${packages[pkgnum]}" | {
  202.             files=0
  203.             while read file
  204.             do
  205.                 if [[ $file == /usr/* ]] \
  206.                    && [ -f "/opt/relocated/${packages[pkgnum]}/$file" ]
  207.                 then
  208.                     (( files++ ))
  209.                     if ! undo "$file" "${packages[pkgnum]}"
  210.                     then
  211.                         echo "Fatal error: Failed to undo relocation of $file"
  212.                         exit 1
  213.                     fi
  214.                 fi
  215.             done
  216.             if (( files > 0 ))
  217.             then
  218.                 echo "Cleaning up..."
  219.                 rm -rf "/opt/relocated/${packages[pkgnum]}"
  220.             else
  221.                 echo "Not cleaning up: Suspiciously, no files were unrelocated"
  222.             fi
  223.         }
  224.         ;;
  225.     esac
  226. done
  227.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement