Advertisement
Guest User

Untitled

a guest
Aug 31st, 2009
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.24 KB | None | 0 0
  1. #!/bin/sh
  2.  
  3. # Paludis-aware version
  4. #- a hack
  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.  
  132. # The meat of it - rebuilding the ebuilds
  133. # ALL emerges are oneshots - we don't want to mess with the world file
  134. # We first attempt to emerge the specific module that was installed last time
  135. # If that fails, we attempt to install a newer version
  136.  
  137. ebuild_rebuild() {
  138.  
  139. echo ""
  140. echo "$(date) : Rebuilding modules: Building list of ebuilds" | tee -a $LOG
  141. if [ -s ${MODULES_LIST} ]; then
  142. for line in $(sort -u ${MODULES_LIST}); do
  143. echo "$line"|sed -e 's|.*pkg/||' -e 's|/CONTENTS||'|fgrep -v "dev-lang/perl" >>${EBUILDS_PREINSTALL}
  144. done
  145. fi
  146.  
  147. # If they asked for interactive, let them see what will be reinstalled
  148. if [ -s ${EBUILDS_PREINSTALL} ]; then
  149.  
  150. if [ ! -z $ASK ]; then
  151. echo "Press Enter to see the list of ebuilds we'll be evaluating"
  152. read key
  153. $PAGER ${EBUILDS_PREINSTALL}
  154. printf "Continue? (Y/N) "
  155. read ANSWER
  156. if [ $(echo "${ANSWER}" | grep -i -e "^n|N" ) ]; then
  157. echo "$(date) : USER ABORTED REBUILD">>$LOG
  158. exit
  159. fi
  160. fi
  161.  
  162. for EBUILD in $(cat ${EBUILDS_PREINSTALL} ); do
  163. if [ -z $PALUDIS ];then
  164. # Use the esync cache if available
  165. if [ -x /usr/bin/esearch ]; then
  166. EBUILD=`echo $EBUILD | sed -e 's/-[0-9].*//'`
  167. INFO=$(/usr/bin/esearch --fullname --instonly --own='%p:%vi:%va:%m' $EBUILD)
  168. #FULLNAME=`echo $INFO | cut -d':' -f1`
  169. INSTALLED=`echo $INFO | cut -d':' -f2`
  170. AVAILABLE=`echo $INFO | cut -d':' -f3`
  171. MASKED=`echo $INFO | cut -d':' -f4`
  172. if [ ! -z "$MASKED" ]; then
  173. echo ""
  174. echo "$(date) : There are no unmasked ebuilds to satisfy $EBUILD. Skipping" | tee -a $LOG
  175. sleep 2
  176. else
  177. if [ "$INSTALLED" != "$AVAILABLE" -a -n "$ASK" ]; then
  178. printf "${EBUILD}-${INSTALLED} is not the latest available. Use version ${AVAILABLE}? (Y/n) "
  179. read ANSWER
  180. if [ $(echo "${ANSWER}" | grep -i "^n" ) ]; then
  181. # re-install the current version
  182. echo "=${EBUILD}-${INSTALLED}" >> ${EBUILDS_ORDERED}
  183. else
  184. # we want the latest available
  185. echo "$EBUILD" >> ${EBUILDS_ORDERED}
  186. echo "$(date) : User chose to install ${EBUILD}-${AVAILABLE}" >> $LOG
  187. fi
  188. else
  189. # assume we want the latest available
  190. echo "$EBUILD" >> ${EBUILDS_ORDERED}
  191. fi
  192. fi
  193. else
  194. # No cache available - use the old method
  195. if emerge --oneshot -p "=$EBUILD"|egrep -q ".*ebuilds.*satisfy"; then
  196. if emerge --oneshot -p ">=$EBUILD"|egrep -q ".*ebuilds.*satisfy"; then
  197. echo "$(date) : There are no unmasked ebuilds to satisfy $EBUILD. Skipping" | tee -a $LOG
  198. sleep 2
  199. else
  200. if [ ! -z $ASK ]; then
  201. printf "${EBUILD} isn't available, but a new version is. Install? (Y/N) "
  202. read ANSWER
  203. if [ $(echo "${ANSWER}" | egrep -e "^y|Y" ) ]; then
  204. echo ">=$EBUILD" >> ${EBUILDS_ORDERED}
  205. echo "$(date) : User chose to install >=${EBUILD}">>$LOG
  206. fi
  207. else
  208. echo ">=$EBUILD" >>${EBUILDS_ORDERED}
  209. fi
  210. fi
  211. else
  212. echo "=$EBUILD">>${EBUILDS_ORDERED}
  213. fi
  214. fi
  215. else
  216. # Paludis
  217. if ! paludis -q "=$EBUILD" --no-suggestions --compact > /dev/null 2>&1; then
  218. if ! paludis -q ">=$EBUILD" --no-suggestions --compact > /dev/null 2>&1; then
  219. echo "$(date) : There are no unmasked ebuilds to satisfy $EBUILD. Skipping" | tee -a $LOG
  220. sleep 2
  221. else
  222. if [ ! -z $ASK ]; then
  223. printf "${EBUILD} isn't available, but a new version is. Install? (Y/N) "
  224. read ANSWER
  225. if [ $(echo "${ANSWER}" | egrep -e "^y|Y" ) ]; then
  226. echo ">=$EBUILD" >> ${EBUILDS_ORDERED}
  227. echo "$(date) : User chose to install >=${EBUILD}">>$LOG
  228. fi
  229. else
  230. echo ">=$EBUILD" >>${EBUILDS_ORDERED}
  231. fi
  232. fi
  233. else
  234. echo "=$EBUILD">>${EBUILDS_ORDERED}
  235. fi
  236. fi
  237. done
  238.  
  239. if [ -s ${EBUILDS_ORDERED} ]; then
  240. if [ ! -z $ASK ]; then
  241. echo "Press Enter to see the final list of ebuilds to install"
  242. read key
  243. $PAGER ${EBUILDS_ORDERED}
  244. printf "Continue? (Y/N) "
  245. read ANSWER
  246. if [ $(echo "${ANSWER}" | egrep -e "^n|N" ) ]; then
  247. echo "$(date) : USER ABORTED REBUILD">>$LOG
  248. exit
  249. fi
  250. fi
  251.  
  252. if [ -z $PALUDIS ]; then
  253. # Cut down to one line so portage can handle ordering these appropriately
  254. emerge -pq --oneshot $(cat ${EBUILDS_ORDERED}) | sed -n -e 's/^\[ebuild .*\] \([^ ]*\).*/=\1/p' >>${EBUILDS_REINSTALL}
  255.  
  256. echo ""
  257. echo "Reinstalling ebuilds"
  258. echo "$(date) : Ebuilds to reinstall: ">>$LOG
  259. cat ${EBUILDS_REINSTALL}>>$LOG
  260. echo >>$LOG
  261.  
  262. # Now that we have them in the right order, emerge them one at a time
  263. # This is to avoid problems if one doesn't emerge correctly
  264.  
  265. for EBUILD in $(cat ${EBUILDS_REINSTALL}); do
  266. emerge --oneshot ${EMERGE_OPTIONS} "$EBUILD"
  267. done
  268. else
  269. # Paludis does ordering and handle spurious errors
  270. paludis -i1 --continue-on-failure always ${PALUDIS_OPTIONS} $(cat ${EBUILDS_ORDERED})
  271. fi
  272. else
  273. echo
  274. echo "Nothing to reinstall!"
  275. echo
  276. fi
  277. else
  278. echo
  279. echo "Nothing to reinstall!"
  280. echo
  281. fi
  282.  
  283. }
  284.  
  285. # Locate .so's and binaries linked against libperl.so
  286. # The coup is in ! -newer libperl.so - cut out anything that was obviously installed
  287. # after our last install of libperl, which should cut out the false positives.
  288.  
  289. libperl_list() {
  290. echo ""
  291. echo "$(date) : Locating ebuilds linked against libperl" | tee -a $LOG
  292. for i in $(find $(egrep -v "^#" /etc/ld.so.conf) -type f -name '*.so*' ! -newer /usr/lib/libperl.so 2>/dev/null) \
  293. $(find $(echo $PATH | sed 's/:/ /g') -type f -perm +0111 ! -newer /usr/lib/libperl.so 2>/dev/null) ;
  294. do
  295. if [ -f ${i} ]; then
  296. if ldd ${i} 2>&1 | fgrep "libperl" - >/dev/null; then
  297. for file in $PKGDIR/*/*/CONTENTS; do
  298. fgrep -l " $i " $file
  299. done >>${MODULES_LIST};
  300. fi
  301. fi
  302. done
  303.  
  304. }
  305.  
  306. # Assuming a successful module run, look to see whats left over
  307. leftovers() {
  308. echo ""
  309. echo "$(date) : Finding left over modules" | tee -a $LOG
  310.  
  311. echo ""
  312. echo "$(date) : The following files remain. These were either installed by hand" | tee -a $LOG
  313. echo "$(date) : or edited. This script cannot deal with them." | tee -a $LOG
  314. echo | tee -a $LOG
  315.  
  316.  
  317. INC=$(perl -e 'for $line (@INC) { next if $line eq "."; next if $line =~ m/'${PERL_VERSION}'/; print "$line\n" }')
  318. for file in $(find $INC -type f 2>/dev/null |fgrep -v "${gPERL_VERSION}" ) ; do
  319. echo "$(date) : ${file}" | tee -a $LOG
  320. done
  321. }
  322.  
  323. usage() {
  324. echo "Usage: $0 [options] [paludis] [ask]"
  325. printf "\tmodules - rebuild perl modules for old installs of perl\n"
  326. printf "\tallmodules - rebuild perl modules for any install of perl\n"
  327. printf "\tlibperl - rebuild anything linked against libperl\n"
  328. printf "\tph-clean - clean out old ph files from a previous perl\n"
  329. printf "\tphupdate - update existing ph files, useful after an upgrade to system parts like the kernel\n"
  330. printf "\tphall - clean out old ph files and run phupdate\n"
  331. printf "\tall - rebuild modules, libperl linkages, clean ph files, and rebuild them\n"
  332. printf "\treallyall - rebuild modules for any install of perl, libperl linkages, clean ph files, and rebuild them\n"
  333. printf "\n"
  334. printf "\task - ask for confirmation on each emerge\n"
  335. printf "\tpaludis - use the paludis package mangler\n"
  336. printf "\n"
  337. exit 0
  338. }
  339.  
  340. if [ -z "$1" ]; then
  341. usage
  342. fi
  343.  
  344. EMERGE_OPTIONS=""
  345. PALUDIS_OPTIONS=""
  346. ASK=""
  347. PALUDIS=""
  348. MODULES=false
  349. LIBPERL=false
  350. PHCLEAN=false
  351. PHUPDATE=false
  352. FORCE=false
  353. LEFTOVERS=false
  354. while [ ! -z "$1" ] ; do
  355. case "$1" in
  356. help | --help | -h )
  357. usage
  358. ;;
  359. leftovers )
  360. LEFTOVERS=true
  361. shift
  362. ;;
  363. modules )
  364. MODULES=true
  365. # LEFTOVERS=true
  366. shift
  367. ;;
  368. allmodules )
  369. MODULES=true
  370. FORCE=true
  371. shift
  372. ;;
  373. libperl )
  374. LIBPERL=true
  375. shift
  376. ;;
  377. paludis )
  378. PALUDIS="true"
  379. shift
  380. ;;
  381. ph-clean )
  382. PHCLEAN=true
  383. shift
  384. ;;
  385. phupdate )
  386. PHUPDATE=true
  387. shift
  388. ;;
  389. phall )
  390. PHCLEAN=true
  391. PHUPDATE=true
  392. shift
  393. ;;
  394. all )
  395. MODULES=true
  396. LIBPERL=true
  397. PHCLEAN=true
  398. PHUPDATE=true
  399. LEFTOVERS=true
  400. shift
  401. ;;
  402. reallyall )
  403. MODULES=true
  404. LIBPERL=true
  405. PHCLEAN=true
  406. PHUPDATE=true
  407. FORCE=true
  408. shift
  409. ;;
  410. ask )
  411. ASK="true"
  412. EMERGE_OPTIONS="${EMERGE_OPTIONS} --ask"
  413. shift
  414. ;;
  415. force )
  416. FORCE=true
  417. shift
  418. ;;
  419. * )
  420. EMERGE_OPTIONS="${EMERGE_OPTIONS} $1"
  421. PALUDIS_OPTIONS="${PALUDIS_OPTIONS} $1"
  422. shift
  423. ;;
  424. esac
  425. done
  426.  
  427. if [ ! -z $PALUDIS ];then
  428. PKGDIR=$(paludis --configuration-variable installed location)
  429. else
  430. PKGDIR=$(/usr/bin/portageq vdb_path)
  431. fi
  432.  
  433. $FORCE && PERL_VERSION="0.0.0" && gPERL_VERSION="0\.0\.0"
  434. $PHCLEAN && ph_clean
  435. $PHUPDATE && ph_update
  436. $MODULES && module_list
  437. $LIBPERL && libperl_list
  438. ($MODULES || $LIBPERL) && ebuild_rebuild
  439. $LEFTOVERS && leftovers
  440.  
  441. #postclean
  442.  
  443. exit
  444. # vim:ts=3:sw=3:et
  445.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement