SHARE
TWEET

Untitled

a guest Sep 6th, 2009 29 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/sh
  2.  
  3. # Paludis-aware version
  4. #- a hack, second try
  5. # Version 1.4
  6. #- patches from Wade Fitzpatrick for equery and fgrep suggestions (bug 125674),
  7. #- patches from Joerge Plate for grep being called with too many arguments (bug 114155)
  8. #- finally updated emerge syntax, brought up by nyhm (with some input from cab) in bug 128130.
  9. # Version 1.3
  10. # sort of a changelog if you want to call it that...
  11. # grep -E '/usr/lib*/perl5/' */*/CONTENTS > to make my list :)
  12. # version 1.2 - swtaylor gave some good pointers on making the tmp files, as well as reminding me of grep's -f functionality :)
  13. # version 1.1 - Mr. Bones gave a lot of good input on cleaning up the script
  14. # Version 1 - stuff
  15.  
  16. # First and foremost - make sure we have a perl to work with...
  17. PERL=$(which perl)
  18. if [ "${PERL}x" = "x" ]; then
  19.    echo "NO PERL INSTALLED!! (at least not in your path)"
  20.    exit
  21. fi
  22. eval $(perl '-V:version')
  23. PERL_VERSION=${version}
  24. gPERL_VERSION=`echo $PERL_VERSION|sed -e 's|\.|\\\.|g'`
  25. . /etc/init.d/functions.sh || {
  26.         echo "$0: Could not source /init.d/functions.sh!"
  27.         exit 1
  28. }
  29.  
  30. TMPDIR=${TMPDIR:-/tmp}
  31.  
  32. DATESTAMP=$(date +"%Y%m%d%H%M%S")
  33. LOG=$(mktemp ${TMPDIR}/perl-cleaner.log.$DATESTAMP.XXXXXXXXXX)
  34. PAGER=${PAGER:-more}
  35.  
  36. # Set up our temporary files
  37. MODULES_LIST=$(mktemp ${TMPDIR}/modules.list.XXXXXXXXXX)
  38. EBUILDS_PREINSTALL=$(mktemp ${TMPDIR}/ebuilds.preinstall.XXXXXXXXXX)
  39. EBUILDS_ORDERED=$(mktemp ${TMPDIR}/ebuilds.ordered.XXXXXXXXXX)
  40. EBUILDS_REINSTALL=$(mktemp ${TMPDIR}/ebuilds.reinstall.XXXXXXXXXX)
  41.  
  42. postclean() {
  43.    for FILE in ${MODULES_LIST} ${EBUILDS_PREINSTALL} ${EBUILDS_ORDERED} ${EBUILDS_REINSTALL}; do
  44.  
  45.       if [ -f $FILE ]; then
  46.          rm -f $FILE
  47.       fi
  48.  
  49.    done
  50.  
  51.    if [ -s $LOG ]; then
  52.       echo
  53.       echo "For a complete log, please read $LOG"
  54.       echo
  55.    else
  56.       if [ -f $LOG ]; then
  57.         rm -f $LOG
  58.       fi
  59.    fi
  60. }
  61.  
  62. # This is to clean out the old .ph files generated in our last perl install
  63. ph_clean() {
  64.    echo ""
  65.    echo "$(date) : Beginning a clean up of .ph files" | tee -a $LOG
  66.    echo "Excluding perl-${PERL_VERSION} from cleaning" | tee -a $LOG
  67.  
  68.    local PV=${version}
  69.    local gPV=`echo $PV|sed -e 's|\.|\\\.|g'`
  70.    INC=$(perl -e 'for $line (@INC) { next if $line eq "."; next if $line =~
  71.    m/'${PV}'/; print "$line\n" }')
  72.    if [ "${INC}x" != "x" ]; then
  73.    echo "Locating ph files for removal"
  74.       for file in $(find $INC -name "*.ph" -type f 2>/dev/null); do
  75.          if [ ! $(echo "$file"|grep $gPV) ]; then
  76.             echo ""
  77.             echo "$(date) : Removing old ph file: $file" | tee -a $LOG
  78.             rm $file
  79.          fi
  80.       done
  81.    fi
  82.  
  83.    # Silently remove those dirs that we just emptied
  84.    find $INC -depth -type d 2>/dev/null | grep -v $gPV | xargs -r rmdir 2>/dev/null
  85. }
  86.  
  87. # Generate ph files; this is useful if we've upgraded packages with headers so that perl knows the new info
  88. ph_update() {
  89.    echo ""
  90.    echo "$(date) : Updating ph files" | tee -a $LOG
  91.    cd /usr/include; h2ph * | tee -a $LOG
  92.    cd /usr/include; h2ph -r sys/* arpa/* netinet/* bits/* security/* asm/* gnu/* linux/* gentoo* | tee -a $LOG
  93.    cd /usr/include/linux; h2ph * | tee -a $LOG
  94. }
  95.  
  96.  
  97. # Build a list of modules installed under older perls - only valid if the module was an ebuild :)
  98. module_list() {
  99.    echo ""
  100.    echo "$(date) : Building list of modules for reinstall" | tee -a $LOG
  101.    echo "Locating modules for reinstall"
  102.     for checkfile in `find $PKGDIR -maxdepth 3 -mindepth 3 -name "CONTENTS" |xargs grep -El '/usr/lib*/perl5/' `; do
  103.         if [ "`grep -l "${gPERL_VERSION}" $checkfile`x" = "x" ]; then
  104.                  echo "$checkfile" >> ${MODULES_LIST}
  105.         fi;
  106.     done
  107. }
  108.  
  109. alternate_module_list() {
  110.    # Takes longer to run, but identifes modules not associated with
  111.    # an ebuild.
  112.    #
  113.    # Reset INC - INC is dynamically generated, and if we removed any ph
  114.    # files - and they were the only thing left in a dir - then there's
  115.    # no sense in revisiting that dir
  116.    echo ""
  117.    echo "$(date) : Building list of modules for reinstall" | tee -a $LOG
  118.    INC=$(perl -e 'for $line (@INC) { next if $line eq "."; next if $line =~ m/'${PERL_VERSION}'/; print "$line\n" }')
  119.    INSTALLED_EBUILDS=$(find $PKGDIR -name CONTENTS)
  120.    echo "Locating modules for reinstall"
  121.    for file in $(find $INC -iname "*.pm" \! -type f 2>/dev/null | fgrep -v "${gPERL_VERSION}"| sort -u); do
  122.       PKG=$(for ebuild in $INSTALLED_EBUILDS; do if fgrep -l $file $ebuild; then break; fi; done)
  123.       if [ -z "$PKG" ] ; then
  124.          echo "Warning: $file is not owned by a currently installed ebuild"
  125.       else
  126.          echo "$PKG" >>${MODULES_LIST}
  127.       fi
  128.    done
  129. }
  130.  
  131. # ebuild_find searches the repositories for ebuilds
  132. # note the ! in front of paludis to get the same
  133. # return state as the emerge/grep combo
  134. ebuild_find() {
  135.     if [ -z $PALUDIS ]; then
  136.         emerge --oneshot -p $1|egrep -q ".*ebuilds.*satisfy"
  137.     else
  138.         ! paludis -q $1 --no-suggestions --compact > /dev/null 2>&1
  139.     fi
  140.     STATUS=$?
  141.     return $STATUS
  142. }
  143.  
  144. # The meat of it - rebuilding the ebuilds
  145. # ALL emerges are oneshots - we don't want to mess with the world file
  146. # We first attempt to emerge the specific module that was installed last time
  147. # If that fails, we attempt to install a newer version
  148.  
  149. ebuild_rebuild() {
  150.  
  151.    echo ""
  152.    echo "$(date) : Rebuilding modules: Building list of ebuilds" | tee -a $LOG
  153.    if [ -s ${MODULES_LIST} ]; then
  154.       for line in $(sort -u ${MODULES_LIST}); do
  155.          echo "$line"|sed -e 's|.*pkg/||' -e 's|/CONTENTS||'|fgrep -v "dev-lang/perl" >>${EBUILDS_PREINSTALL}
  156.       done
  157.    fi
  158.  
  159.    # If they asked for interactive, let them see what will be reinstalled
  160.    if [ -s ${EBUILDS_PREINSTALL} ]; then
  161.  
  162.       if [ ! -z $ASK ]; then
  163.          echo "Press Enter to see the list of ebuilds we'll be evaluating"
  164.          read key
  165.          $PAGER ${EBUILDS_PREINSTALL}
  166.          printf "Continue? (Y/N) "
  167.          read ANSWER
  168.          if [ $(echo "${ANSWER}" | grep -i -e "^n|N" ) ]; then
  169.             echo "$(date) : USER ABORTED REBUILD">>$LOG
  170.             exit
  171.          fi
  172.       fi
  173.  
  174.       for EBUILD in $(cat ${EBUILDS_PREINSTALL} ); do
  175. # Use the esync cache if available
  176.          if [ -z $PALUDIS ] && [ -x /usr/bin/esearch ]; then
  177.             EBUILD=`echo $EBUILD | sed -e 's/-[0-9].*//'`
  178.             INFO=$(/usr/bin/esearch --fullname --instonly --own='%p:%vi:%va:%m' $EBUILD)
  179.             #FULLNAME=`echo $INFO | cut -d':' -f1`
  180.             INSTALLED=`echo $INFO | cut -d':' -f2`
  181.             AVAILABLE=`echo $INFO | cut -d':' -f3`
  182.             MASKED=`echo $INFO | cut -d':' -f4`
  183.             if [ ! -z "$MASKED" ]; then
  184.                echo ""
  185.                echo "$(date) : There are no unmasked ebuilds to satisfy $EBUILD. Skipping" | tee -a $LOG
  186.                sleep 2
  187.             else
  188.                if [ "$INSTALLED" != "$AVAILABLE" -a -n "$ASK" ]; then
  189.                   printf "${EBUILD}-${INSTALLED} is not the latest available. Use version ${AVAILABLE}? (Y/n) "
  190.                   read ANSWER
  191.                   if [ $(echo "${ANSWER}" | grep -i "^n" ) ]; then
  192.                      # re-install the current version
  193.                      echo "=${EBUILD}-${INSTALLED}" >> ${EBUILDS_ORDERED}
  194.                   else
  195.                      # we want the latest available
  196.                      echo "$EBUILD" >> ${EBUILDS_ORDERED}
  197.                      echo "$(date) : User chose to install ${EBUILD}-${AVAILABLE}" >> $LOG
  198.                   fi
  199.                else
  200.                   # assume we want the latest available
  201.                   echo "$EBUILD" >> ${EBUILDS_ORDERED}
  202.                fi
  203.             fi
  204.          else
  205. # No cache available - use the old method
  206.          if ebuild_find "=$EBUILD"; then
  207.             if ebuild_find ">=$EBUILD"; then
  208.                echo "$(date) : There are no unmasked ebuilds to satisfy $EBUILD. Skipping" | tee -a $LOG
  209.                sleep 2
  210.             else
  211.                if [ ! -z $ASK ]; then
  212.                   printf "${EBUILD} isn't available, but a new version is. Install? (Y/N) "
  213.                   read ANSWER
  214.                   if [ $(echo "${ANSWER}" | egrep -e "^y|Y" ) ]; then
  215.                      echo ">=$EBUILD" >> ${EBUILDS_ORDERED}
  216.                      echo "$(date) : User chose to install >=${EBUILD}">>$LOG
  217.                   fi
  218.                else
  219.                   echo ">=$EBUILD" >>${EBUILDS_ORDERED}
  220.                fi
  221.             fi
  222.          else
  223.             echo "=$EBUILD">>${EBUILDS_ORDERED}
  224.          fi
  225.          fi
  226.       done
  227.  
  228.       if [ -s ${EBUILDS_ORDERED} ]; then
  229.          if [ ! -z $ASK ]; then
  230.             echo "Press Enter to see the final list of ebuilds to install"
  231.             read key
  232.             $PAGER ${EBUILDS_ORDERED}
  233.             printf "Continue? (Y/N) "
  234.             read ANSWER
  235.             if [ $(echo "${ANSWER}" | egrep -e "^n|N" ) ]; then
  236.                echo "$(date) : USER ABORTED REBUILD">>$LOG
  237.                exit
  238.             fi
  239.          fi
  240.  
  241.          if [ -z $PALUDIS ]; then
  242.              # Cut down to one line so portage can handle ordering these appropriately
  243.              emerge -pq --oneshot $(cat ${EBUILDS_ORDERED}) | sed -n -e 's/^\[ebuild .*\] \([^ ]*\).*/=\1/p' >>${EBUILDS_REINSTALL}
  244.  
  245.              echo ""
  246.              echo "Reinstalling ebuilds"
  247.              echo "$(date) : Ebuilds to reinstall: ">>$LOG
  248.              cat ${EBUILDS_REINSTALL}>>$LOG
  249.              echo >>$LOG
  250.  
  251.              # Now that we have them in the right order, emerge them one at a time
  252.              # This is to avoid problems if one doesn't emerge correctly
  253.  
  254.              for EBUILD in $(cat ${EBUILDS_REINSTALL}); do
  255.                  emerge --oneshot ${EMERGE_OPTIONS} "$EBUILD"
  256.              done
  257.          else
  258.              # Paludis does ordering and handle spurious errors
  259.              paludis -i1 --continue-on-failure always ${PALUDIS_OPTIONS} $(cat ${EBUILDS_ORDERED})
  260.          fi
  261.       else
  262.          echo
  263.          echo "Nothing to reinstall!"
  264.          echo
  265.       fi
  266.    else
  267.       echo
  268.       echo "Nothing to reinstall!"
  269.       echo
  270.    fi
  271.  
  272. }
  273.  
  274. # Locate .so's and binaries linked against libperl.so
  275. # The coup is in ! -newer libperl.so - cut out anything that was obviously installed
  276. # after our last install of libperl, which should cut out the false positives.
  277.  
  278. libperl_list() {
  279.    echo ""
  280.    echo "$(date) : Locating ebuilds linked against libperl" | tee -a $LOG
  281.    for i in $(find $(egrep -v "^#" /etc/ld.so.conf) -type f -name '*.so*' ! -newer /usr/lib/libperl.so 2>/dev/null) \
  282.             $(find $(echo $PATH | sed 's/:/ /g') -type f -perm +0111 ! -newer /usr/lib/libperl.so 2>/dev/null) ;
  283.    do
  284.       if [ -f ${i} ]; then
  285.          if ldd ${i} 2>&1 | fgrep "libperl" - >/dev/null; then
  286.             for file in $PKGDIR/*/*/CONTENTS; do
  287.                fgrep -l " $i " $file
  288.             done >>${MODULES_LIST};
  289.          fi  
  290.       fi
  291.    done
  292.  
  293. }
  294.  
  295. # Assuming a successful module run, look to see whats left over
  296. leftovers() {
  297.    echo ""
  298.    echo "$(date) : Finding left over modules" | tee -a $LOG
  299.  
  300.    echo ""
  301.    echo "$(date) : The following files remain. These were either installed by hand" | tee -a $LOG
  302.    echo "$(date) : or edited. This script cannot deal with them." | tee -a $LOG
  303.    echo | tee -a $LOG
  304.  
  305.  
  306.    INC=$(perl -e 'for $line (@INC) { next if $line eq "."; next if $line =~ m/'${PERL_VERSION}'/; print "$line\n" }')
  307.    for file in $(find $INC -type f 2>/dev/null |fgrep -v  "${gPERL_VERSION}" ) ; do
  308.       echo "$(date) : ${file}" | tee -a $LOG
  309.    done
  310. }
  311.  
  312. usage() {
  313.    echo "Usage: $0 [options] [paludis] [ask]"
  314.    printf "\tmodules - rebuild perl modules for old installs of perl\n"
  315.    printf "\tallmodules - rebuild perl modules for any install of perl\n"
  316.    printf "\tlibperl - rebuild anything linked against libperl\n"
  317.    printf "\tph-clean - clean out old ph files from a previous perl\n"
  318.    printf "\tphupdate - update existing ph files, useful after an upgrade to system parts like the kernel\n"
  319.    printf "\tphall - clean out old ph files and run phupdate\n"
  320.    printf "\tall - rebuild modules, libperl linkages, clean ph files, and rebuild them\n"
  321.    printf "\treallyall - rebuild modules for any install of perl, libperl linkages, clean ph files, and rebuild them\n"
  322.    printf "\n"
  323.    printf "\task - ask for confirmation on each emerge\n"
  324.    printf "\tpaludis - use the paludis package mangler\n"
  325.    printf "\n"
  326.    exit 0
  327. }
  328.  
  329. if [ -z "$1" ]; then
  330.    usage
  331. fi
  332.  
  333. EMERGE_OPTIONS=""
  334. PALUDIS_OPTIONS=""
  335. ASK=""
  336. PALUDIS=""
  337. MODULES=false
  338. LIBPERL=false
  339. PHCLEAN=false
  340. PHUPDATE=false
  341. FORCE=false
  342. LEFTOVERS=false
  343. while [ ! -z "$1" ] ; do
  344.    case "$1" in
  345.       help | --help | -h )
  346.          usage
  347.          ;;
  348.       leftovers )
  349.          LEFTOVERS=true
  350.          shift
  351.          ;;
  352.       modules )
  353.          MODULES=true
  354. #         LEFTOVERS=true
  355.          shift
  356.          ;;
  357.       allmodules )
  358.          MODULES=true
  359.          FORCE=true
  360.          shift
  361.          ;;
  362.       libperl )
  363.          LIBPERL=true
  364.          shift
  365.          ;;
  366.       paludis )
  367.          PALUDIS="true"
  368.          shift
  369.          ;;
  370.       ph-clean )
  371.          PHCLEAN=true
  372.          shift
  373.          ;;
  374.       phupdate )
  375.          PHUPDATE=true
  376.          shift
  377.          ;;
  378.       phall )
  379.          PHCLEAN=true
  380.          PHUPDATE=true
  381.          shift
  382.          ;;
  383.       all )
  384.          MODULES=true
  385.          LIBPERL=true
  386.          PHCLEAN=true
  387.          PHUPDATE=true
  388.          LEFTOVERS=true
  389.          shift
  390.          ;;
  391.       reallyall )
  392.          MODULES=true
  393.          LIBPERL=true
  394.          PHCLEAN=true
  395.          PHUPDATE=true
  396.          FORCE=true
  397.         shift
  398.          ;;
  399.       ask )
  400.          ASK="true"
  401.          EMERGE_OPTIONS="${EMERGE_OPTIONS} --ask"
  402.          shift
  403.          ;;
  404.       force )
  405.          FORCE=true
  406.          shift
  407.          ;;
  408.       * )
  409.          EMERGE_OPTIONS="${EMERGE_OPTIONS} $1"
  410.          PALUDIS_OPTIONS="${PALUDIS_OPTIONS} $1"
  411.          shift
  412.          ;;
  413.    esac
  414. done
  415.  
  416. if [ ! -z $PALUDIS ];then
  417.     PKGDIR=$(paludis --configuration-variable installed location)
  418. else
  419.     PKGDIR=$(/usr/bin/portageq vdb_path)
  420. fi
  421.  
  422. $FORCE && PERL_VERSION="0.0.0" && gPERL_VERSION="0\.0\.0"
  423. $PHCLEAN && ph_clean
  424. $PHUPDATE && ph_update
  425. $MODULES && module_list
  426. $LIBPERL && libperl_list
  427. ($MODULES || $LIBPERL) && ebuild_rebuild
  428. $LEFTOVERS && leftovers
  429.  
  430. #postclean
  431.  
  432. exit
  433. # vim:ts=3:sw=3:et
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top