PageRenderTime 28ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/bin/tpinstall

http://tarp-package-manager.googlecode.com/
Korn Shell | 1503 lines | 953 code | 157 blank | 393 comment | 215 complexity | b74fb429b09ea6ed34c3d3162d214ba6 MD5 | raw file
  1. #!/usr/bin/ksh
  2. #########################################################################
  3. # #
  4. # Name: tpinstall (shell script) #
  5. # #
  6. # Completed: 28th August, 2003. #
  7. # #
  8. # Updated: 5th July, 2004. #
  9. # #
  10. # Author: Simon Edwards, Proprius Consulting Ltd. #
  11. # #
  12. # Arguments: Commit a package: #
  13. # -c -p pkg [-v] #
  14. # -c Indicate we wish to commit the package #
  15. # -p Specifies the name of the package #
  16. # -v Verbose mode, show progress messages. #
  17. # #
  18. # Install a package: #
  19. # -i -d depot -p pkgfile [-f] [-v] [-r dir] [l] [-n] [-s] #
  20. # -P #
  21. # -i Indicate we wish to install the package #
  22. # -d Directory containing the tarp files. #
  23. # -p The file containing the tarp package. #
  24. # [See notes on PACKAGE FILES below for more #
  25. # details.] #
  26. # -f Force installation, (allowing the same version #
  27. # or an older version to be installed). #
  28. # -v Verbose mode, show progress messages. #
  29. # -r Indicates the top level directory to install #
  30. # to, overriding the ROOTDIR setting in the #
  31. # package specification. #
  32. # -l List the dependencies for installing the #
  33. # package and then exit. #
  34. # -x Ignore dependency installation, just install #
  35. # the required package. #
  36. # -n Do not commit the package - leave it in #
  37. # installed state. #
  38. # -s Do not run the postinstall.perms script - #
  39. # leaving permissions to default values. #
  40. # [Useful when installing the packages that are #
  41. # by default owned by somebody else]. #
  42. # [When running as a normal user the chown #
  43. # will now be ignored.] #
  44. # -P Preview mode - (best used with verbose mode) #
  45. # show the details pertaining to the installation #
  46. # without actually performing the install. #
  47. # #
  48. # Purpose: #
  49. # #
  50. # This program will install a tarp package. The tarp PACKAGE FILE #
  51. # is a tar file which contains the programs to install - relative to #
  52. # the root directory - as well as the following special files: #
  53. # #
  54. # spec The package specification file, which must contain #
  55. # at least the following fields: #
  56. # NAME, DESCRIPTION, VERSION. #
  57. # Optionally includes VENDOR, LICENSE, ROOTDIR, #
  58. # and DEPENDENCIES. #
  59. # #
  60. # checkinstall A script to run to check to see if the package can be #
  61. # installed. If returns 0, it can be, if returns 1 it #
  62. # can not be. #
  63. # preinstall A script to extract and run prior to installation - #
  64. # if it returns 0 the package can be installed. If it #
  65. # returns 1 the package can be force installed, and #
  66. # if it returns 2 the package can not be installed. #
  67. # postinstall This script is run when the package has been #
  68. # successfully installed. #
  69. # preremove This script is run before removing the package from #
  70. # the system. #
  71. # postremove This package is run after removing the package from #
  72. # the system. #
  73. # #
  74. # All four of the pre and post install scripts have a #
  75. # variable set called PACKAGE - which is the name of #
  76. # the current package, and VERSION which stores the #
  77. # version of the package. #
  78. # #
  79. # PACKAGE FILES #
  80. # A tarp package (as described above) allows a single #
  81. # package to be installed. However the latest verion #
  82. # also supports installation or update from a TARP #
  83. # BUNDLE. This is a single file that contains a number #
  84. # of package files. #
  85. # #
  86. # A tarp bundle has the extension name of tarpb and #
  87. # contains 1 or more packages. It is possible to #
  88. # specify the name of the bnudle to install all #
  89. # packages, (at least those where the checkinstall #
  90. # script - if it exists - is successful). Or it is #
  91. # possible to upadate from it - just install the #
  92. # components that are newer and are already installed. #
  93. # #
  94. # It is also possible to install just a specified #
  95. # component using the naming scheme of: bundle.package. #
  96. # #
  97. # Package Database: #
  98. # #
  99. # The list of installed packages is kept in a database, #
  100. # usually in /var/adm/tarp. Each package is kept in a #
  101. # sub-directory called the name of the package. This #
  102. # sub-directory contains the current spec file, as well #
  103. # as the pre/post install/remove scripts. #
  104. # #
  105. # This directory also a file called cksums which contains #
  106. # a list of the files installed and the cksum in the #
  107. # format of: #
  108. # /full/path|cksum #
  109. # #
  110. # The checksum is based on the results of cksum if #
  111. # running on HP-UX, or MD5 if running under Linux. #
  112. # #
  113. # The directory also contains a status file which can #
  114. # contain "installed", "committed", "broken". #
  115. # When a package is installed, but not committed, any #
  116. # files that already exist are kept in the directory #
  117. # under a sub-directory called saved_files. #
  118. # #
  119. # In this instance when a installed package is removed, #
  120. # any over-written files are recovered. When a package #
  121. # is committed then these files are removed, meaning #
  122. # de-installation of the package will remove the files #
  123. # completely. #
  124. # #
  125. # A new version of the same package can only be #
  126. # installed if an existing version is committed. #
  127. # #
  128. # If a package is installed from a bundle, or a #
  129. # complete bundle is installed, then the name of the #
  130. # directory the files are installed into is: #
  131. # bundle.package #
  132. # #
  133. # The package name does not need to be unique - so #
  134. # beware. #
  135. # #
  136. # Limitations: [1] Current version does not include all the cleanup #
  137. # functionality when failures occur. This will be #
  138. # added in later versions. #
  139. # #
  140. # VERSION: #(@)1.1 Original (SE) #
  141. # #(@)1.2 Corrected handling of cpio stderr (SE)> #
  142. # #(@)1.3 Updated to support bash (SE)> #
  143. # #(@)1.4 Change integer to typeset -i (SE)> #
  144. # #(@)1.5 Revert to ksh (bash problems) (SE)> #
  145. # #(@)1.7 Log pre/post installation improvements (SE)> #
  146. # #(@)1.8 Correct compress/bzip2 syntax problems (SE)> #
  147. # #(@)1.9 Implement VOLATILE_EXT option info (SE)> #
  148. # #(@)1.10 Fixes of 0007, 0008, 0009 and 0010 (SE)> #
  149. # #(@)1.11 Small syntax correction... #
  150. # #(@)1.12 Support for OVERWRITE in spec file (SE)> #
  151. # #
  152. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
  153. # VERSION HISTORY: #
  154. # #
  155. # Version: 1.12 #
  156. # Date: 6th February, 2004. #
  157. # Author: Simon Edwards, Proprius Consulting Ltd. #
  158. # Changes: Support for OVERWRITE in spec file, which defaults to #
  159. # YES if not specified. If set to NO it means that the #
  160. # package must be removed using tpremove first - newer #
  161. # versions can simply 'update' the previous version. #
  162. # #
  163. # Version: 1.7 #
  164. # Date: 26th December, 2003. #
  165. # Author: Simon Edwards, Proprius Consulting Ltd. #
  166. # Changes: Fixed bug 0002 (so the post installation script is #
  167. # actually run), and improvement 0003 (so the output of #
  168. # pre and post installation scripts are captured and #
  169. # kept). #
  170. # Also modified to support installation from compressed, #
  171. # gzip compressed and bzip2 format archives as well #
  172. # (improvement 0004). #
  173. # #
  174. # Version: 1.3 #
  175. # Date: 4th September, 2003. #
  176. # Author: Simon Edwards, Proprius Consulting Ltd. #
  177. # Changes: Modified to ensure that ARG_DEPOT and ARG_ROOTDIR #
  178. # are exported - allowing them to be used for pre and #
  179. # post installation scripts, (so your know the relative #
  180. # location of the files installed). #
  181. # #
  182. # Version: 1.2 #
  183. # Date: 2nd September, 2003. #
  184. # Author: Simon Edwards, Proprius Consulting Ltd. #
  185. # Changes: Modified the handling of the cpio stderr slightly, #
  186. # since linux dumps out the file names as well as the #
  187. # errors to this file descriptor. #
  188. # Version: #
  189. # Date: #
  190. # Author: #
  191. # Changes: #
  192. # #
  193. #########################################################################
  194. print=print
  195. TMP_BUNDLE_DEPOT=""
  196. export ARG_PKG=""
  197. export ARG_DEPOT=""
  198. export ARG_ROOTDIR=""
  199. ARG_INDENT=0
  200. ARG_FORCE=0
  201. ARG_UPDATE=0
  202. ARG_NOPERMS=0
  203. ARG_VERBOSE=0
  204. ARG_LISTDEPS=0
  205. ARG_NODEPS=0
  206. ARG_NOCOMMIT=0
  207. ARG_PREVIEW=0
  208. ARG_INBUNDLE=""
  209. ind[0]=""
  210. ind[1]=" "
  211. ind[2]=" "
  212. ind[3]=" "
  213. ind[4]=" "
  214. ind[5]=" "
  215. function logmsg
  216. {
  217. [[ $ARG_VERBOSE -eq 1 ]] && $print "MSG : ${ind[$ARG_INDENT]}$1"
  218. }
  219. function logwarn
  220. {
  221. $print "WARN : ${ind[$ARG_INDENT]}$1"
  222. }
  223. function logwarnfile
  224. {
  225. for cline in $(<$1)
  226. do
  227. $print "WARN : ${ind[$ARG_INDENT]}$cline"
  228. done
  229. }
  230. function logerror
  231. {
  232. $print "ERROR: ${ind[$ARG_INDENT]}$1" >&2
  233. [[ -n "$2" ]] && exit $2
  234. }
  235. function logerrorfile
  236. {
  237. for cline in $(<$1)
  238. do
  239. $print "ERROR: ${ind[$ARG_INDENT]}$cline"
  240. done
  241. [[ -n "$2" ]] && exit $2
  242. }
  243. function showscriptinfo
  244. {
  245. typeset XX
  246. XX=$VERBOSE
  247. VERBOSE=1
  248. if [[ -n "$prelogoutput" && -s "$prelogoutput" ]]
  249. then
  250. logmsg "Pre installation script output can be found in $prelogoutput"
  251. fi
  252. if [[ -n "$prelogerror" && -s "$prelogerror" ]]
  253. then
  254. logmsg "Pre installation script errors can be found in $prelogerror"
  255. fi
  256. if [[ -n "$postlogoutput" && -s "$postlogoutput" ]]
  257. then
  258. logmsg "Post installation script output can be found in $postlogoutput"
  259. fi
  260. if [[ -n "$postlogerror" && -s "$postlogerror" ]]
  261. then
  262. logmsg "Post installation script errors can be found in $postlogerror"
  263. fi
  264. VERBOSE=$XX
  265. }
  266. function cleanup
  267. {
  268. typeset dir="$1"
  269. cd
  270. if [[ -n "$TMPDIR" && -d "$TMPDIR" ]]
  271. then
  272. logmsg "Cleaning up directory $TMPDIR"
  273. rm -rf $TMPDIR
  274. fi
  275. if [[ -n "$TMP_BUNDLE_DEPOT" && -d "$TMP_BUNDLE_DEPOT" ]]
  276. then
  277. logmsg "Cleaning up temporary bundle depot $TMP_BUNDLE_DEPOT"
  278. rm -rf $TMP_BUNDLE_DEPOT
  279. else
  280. logmsg "No TMP_BUNDLE_DEPOT defined (no tmp depot to remove)"
  281. fi
  282. #################################################################
  283. # We also remove any old copies of an installed package we #
  284. # have just updated... #
  285. #################################################################
  286. [[ -d $TARP_DB/$ARG_PKG.tmp ]] && rm -rf $TARP_DB/$ARG_PKG.tmp
  287. #################################################################
  288. # Remove any preinstall and postinstall log files that are #
  289. # empty. #
  290. #################################################################
  291. [[ -n "$prelogoutput" && ! -s "$prelogoutput" ]] &&
  292. rm -f $prelogoutput
  293. [[ -n "$prelogerror" && ! -s "$prelogerror" ]] &&
  294. rm -f $prelogerror
  295. [[ -n "$postlogoutput" && ! -s "$postlogoutput" ]] &&
  296. rm -f $postlogoutput
  297. [[ -n "$postlogerror" && ! -s "$postlogerror" ]] &&
  298. rm -f $postlogerror
  299. [[ ! -d "$dir/saved_files" ]] && return
  300. logmsg "Restoring original files..."
  301. (cd $dir/saved_files && tar cpf - . 2>/dev/null) |
  302. (cd $ARG_ROOTDIR && tar xpf - ) || {
  303. logwarn "Unable to restore all files overwritten!";
  304. logwarn "dir=$dir,ARG_ROOTDIR=$ARG_ROOTDIR";
  305. }
  306. [[ -f /tmp/tpinstall-$$.3 ]] && rm -f /tmp/tpinstall-$$.3
  307. }
  308. function usage {
  309. printf "Usage: Installing a package:\n $_PRG -i -p [bundle.]pkg [-d depot] [-f] [-v] [-r root] [-l] [-x] [-n]\n\n" >&2
  310. printf " Preview package installation:\n $_PRG -P -i -p [bundle.]pkg [-d depot] [-f] [-v] [-r root] [-l] [-x] [-n]\n\n" >&2
  311. printf " Comitting a package:\n $_PRG -c -p [bundle.]pkg [-v]\n\n" >&2
  312. printf " Updating a bundle:\n $_PRG -u -c -p bundle [-v]\n\n" >&2
  313. printf "Written by Simon Edwards, Proprius Consulting (www.proprius.co.uk)\n" >&2
  314. printf "For more information please see the $_PRG(1M) manual page.\n\n" >&2
  315. exit 1
  316. }
  317. TARP_DB=${TARP_DB:-/var/adm/tarpdb}
  318. _PRG=$(basename $0)
  319. typeset -i commit=0
  320. typeset -i install=0
  321. [[ -x /opt/oss/bin/gawk ]] && awk=/opt/oss/bin/gawk
  322. [[ -z "$awk" && -x /usr/bin/gawk ]] && awk=/usr/bin/gawk
  323. [[ -z "$awk" && -x /usr/bin/nawk ]] && awk=/usr/bin/nawk
  324. [[ -z "$awk" ]] && awk=awk
  325. [[ ! -d $TARP_DB ]] && {
  326. mkdir -p $TARP_DB 2>/dev/null || {
  327. showscriptinfo;
  328. logerror "Unable to create directory: $TARP_DB" 10;
  329. }
  330. }
  331. if [[ "$($print "$0" | $awk '{print substr($0,1,2)}')" = ".." ]]
  332. then
  333. _PRG2=$PWD/$0
  334. else
  335. [[ "$($print "$0" | $awk '{print substr($0,1,1)}')" = "." ]] &&
  336. _PRG2=$PWD/$_PRG ||
  337. _PRG2=$0
  338. fi
  339. while getopts ":cid:p:fsPxvr:luj:B:" copt
  340. do
  341. case $copt in
  342. B) ARG_INBUNDLE=$OPTARG
  343. ;;
  344. j) ARG_INDENT=$OPTARG
  345. ;;
  346. u) ARG_UPDATE=1
  347. ;;
  348. v) ARG_VERBOSE=1
  349. ;;
  350. s) ARG_NOPERMS=1
  351. ;;
  352. f) ARG_FORCE=1
  353. ;;
  354. n) ARG_NOCOMMIT=1
  355. ;;
  356. c) commit=1
  357. ;;
  358. i) install=1
  359. ;;
  360. x) ARG_NODEPS=1
  361. ;;
  362. l) ARG_LISTDEPS=1
  363. ;;
  364. P) ARG_PREVIEW=1
  365. ;;
  366. d) ARG_DEPOT=$OPTARG
  367. ;;
  368. p) ARG_PKG=$OPTARG
  369. ;;
  370. r) ARG_ROOTDIR=$OPTARG
  371. ;;
  372. ?) usage
  373. ;;
  374. esac
  375. done
  376. BUNDLE=$($print -- "$ARG_PKG" | $awk -v FS="\." 'NF==2 {print $1}')
  377. [[ -n "$BUNDLE" ]] && {
  378. ARG_PKG=$(print "$ARG_PKG" | $awk -v FS="\." '{print $2}');
  379. }
  380. ((install+commit!=1)) && usage
  381. [[ -z "$ARG_PKG" ]] && usage
  382. [[ -z "$ARG_DEPOT" ]] && ARG_DEPOT="$PWD"
  383. ARCH="$(uname -m|sed 's/\///g')"
  384. OS="$(uname)"
  385. [[ -z "$ARG_ROOTDIR" ]] && ARG_ROOTDIR="/"
  386. ((install==1)) && [[ $ARG_PREVIEW -eq 1 ]] &&
  387. logmsg "Previewing installation of package $ARG_PKG.."
  388. logmsg "Package database directory: $TARP_DB"
  389. #########################################################################
  390. # If we have specified a depot, then make sure we are able to find #
  391. # it - and it contains details of the package to install. #
  392. #########################################################################
  393. if [[ $install -eq 1 ]]
  394. then
  395. if [[ -n "$ARG_DEPOT" ]]
  396. then
  397. fc=$($print $ARG_DEPOT|$awk '{print substr($0,1,1);}')
  398. if [[ "$fc" != "/" ]]
  399. then
  400. showscriptinfo
  401. logerror "Depot must be given as absolute path" 12
  402. fi
  403. fi
  404. #################################################################
  405. # We may need to check for a BUNDLE first rather than a #
  406. # package, the methods taken depending on whether BUNDLE is #
  407. # set or not: #
  408. # BUNDLE not set: #
  409. # [1] Check for bundle files - .tarpb, .tarpb.EXT #
  410. # [2] If not found check for package - .tarp, .tarp.EXT #
  411. # [3] Abort if none found #
  412. # #
  413. # BUNDLE set: #
  414. # [1] Check for bundle files - BUNDLE.tarpb, BUNDLE.tarpb.EXT #
  415. # [2] Abort if none found #
  416. # #
  417. # In all cases, EXT can be Z, gz or bz2 #
  418. #################################################################
  419. #################################################################
  420. # Please note that bundle names are in the following format: #
  421. # BUNDLE,version.tarpb[.Z|.gz|.bz2 #
  422. #################################################################
  423. if [[ -n "$BUNDLE" ]]
  424. then
  425. matches="$(cd $ARG_DEPOT; eval ls "${BUNDLE},*.tarpb" "${BUNDLE},*.tarpb.gz" "${BUNDLE},*.tarpb.bz2" "${BUNDLE},*.tarpb.Z" 2>/dev/null)"
  426. else
  427. bmatches="$(cd $ARG_DEPOT; eval ls "${ARG_PKG},*.tarpb" "${ARG_PKG},*.tarpb.gz" "${ARG_PKG},*.tarpb.bz2" "${ARG_PKG},*.tarpb.Z" 2>/dev/null)"
  428. matches="$(cd $ARG_DEPOT; eval ls "${ARG_PKG},*.tarp" "${ARG_PKG},*.tarp.gz" "${ARG_PKG},*.tarp.bz2" "${ARG_PKG},*.tarp.Z" 2>/dev/null)"
  429. if [[ -n "$bmatches" ]]
  430. then
  431. if [[ -n "$matches" ]]
  432. then
  433. logwarn "Package $ARG_PKG matching bundle and package - default to bundle."
  434. else
  435. logmsg "Found matching bundle $ARG_PKG in depot $ARG_DEPOT"
  436. fi
  437. BUNDLE=$ARG_PKG
  438. matches="$bmatches"
  439. ARG_PKG=".*"
  440. fi
  441. fi
  442. if [[ -z "$matches" && $install -eq 1 ]]
  443. then
  444. showscriptinfo
  445. if [[ -n "$BUNDLE" ]]
  446. then
  447. logerror "Unable to find bundle $BUNDLE in depot $ARG_DEPOT" 2
  448. else
  449. logerror "Unable to find package $ARG_PKG in depot $ARG_DEPOT" 2
  450. fi
  451. fi
  452. fi
  453. #########################################################################
  454. # #
  455. # If we do not have a bundle then do the following: #
  456. # If we have a series of matches we need to decide which one we #
  457. # intend to install. To choose the package the following rules are #
  458. # applied: #
  459. # [1] If any files exist for the specified OS-Arch exist, then #
  460. # discard all others from the list. #
  461. # [2] If any files exist for this OS, with no architecture, then #
  462. # discard all others from the list. #
  463. # [3] Discard any files with an OS different from ours. #
  464. # [4] Discard any files with the same OS, but different architecture. #
  465. # #
  466. # From the remaining list choose one which has the highest version #
  467. # number. #
  468. # Remember that the format of the package is as follows: #
  469. # name,version[,OS[,Arch]].tarp #
  470. # #
  471. # If BUNDLE is set then we need to do the following: #
  472. # [1] Sort the version numbers and choose the highest. #
  473. # [2] ARG_PKG is .* or name to install. #
  474. #########################################################################
  475. function get_latest_match
  476. {
  477. $print "$*" |
  478. $awk -v debug=0 -v OS=$OS -v ARCH=$ARCH 'function cmpver(v1,v2,x1,x2) {
  479. split(v1,x1,/-/); split(v2,x2,/-/);
  480. if(x1[1]>x2[1]) return 1;
  481. if(x1[1]<x2[1]) return -1;
  482. if(x1[2]>x2[2]) return 1;
  483. if(x1[2]<x2[2]) return -1;
  484. if(x1[3]>x2[3]) return 1;
  485. if(x1[3]<x2[3]) return -1;
  486. return 0;
  487. }
  488. {
  489. p1=".*,[0-9]+(-[0-9]+)+," OS "," ARCH ".tarp";
  490. p2=".*,[0-9]+(-[0-9]+)+," OS ".tarp";
  491. s1=".*,[0-9]+(-[0-9]+)+";
  492. this=$0;
  493. if(match($0,p1)) {
  494. JUST_THIS_OSARCH=1;
  495. }
  496. if(match($0,p2)) {
  497. JUST_THIS_OS=1;
  498. }
  499. # Get rid of the pkgname and release
  500. sub(s1,"",this);
  501. sub(/\.tarp.*$/,"",this);
  502. if(this == "") {
  503. matches[X++]=$0;
  504. next;
  505. }
  506. if(debug) print "this = " this > "/dev/tty"
  507. # Ignore packages for different operating system
  508. if(JUST_THIS_OSARCH || JUST_THIS_OS)
  509. {
  510. if(substr(this,2,length(OS)) != OS) next;
  511. if(debug) print "OS matched: " OS > "/dev/tty";
  512. }
  513. if(JUST_THIS_OSARCH)
  514. {
  515. x=index(this,",");
  516. # Ignore packages for same OS, but different architecture
  517. if(substr(this,length(this)-length(ARCH)+1) != ARCH) next;
  518. }
  519. matches[X++]=$0;
  520. if(debug) print "Added: " $0 > "/dev/tty";
  521. }
  522. END {
  523. # If JUST_THIS_OSARCH is set, then ignore generic files
  524. # from the list.
  525. p1=".*,[0-9]+(-[0-9]+)+," OS "," ARCH "\\.tarp";
  526. p2=".*,[0-9]+(-[0-9]+)+," OS "\\.tarp";
  527. p3=",[0-9]+(-[0-9]+)+";
  528. if(JUST_THIS_OSARCH) {
  529. X2=0;
  530. for(i in matches) {
  531. match(matches[i],p1);
  532. if(debug) print "Check: " matches[i] > "/dev/tty";
  533. if(RSTART==1) {
  534. matches2[X2++]=matches[i];
  535. }
  536. }
  537. }
  538. if(JUST_THIS_OS && ! JUST_THIS_OSARCH) {
  539. X2=0;
  540. for(i in matches) {
  541. match(matches[i],p2);
  542. if(RSTART==1) {
  543. matches2[X2++]=matches[i];
  544. }
  545. }
  546. }
  547. if(JUST_THIS_OS+JUST_THIS_OSARCH==0) {
  548. if(debug) print "Only match generic packages" > "/dev/tty";
  549. X2=0;
  550. for(i in matches) {
  551. if(debug) print "Check: " matches[i] > "/dev/tty";
  552. matches2[X2++]=matches[i];
  553. }
  554. }
  555. # matches2 contains a list of candidates, so now we
  556. # pick one which has the highest version...
  557. CVERSION="0-0-0";
  558. hadmatch=0;
  559. for(i in matches2) {
  560. match(matches2[i],p3);
  561. if(debug) print matches2[i] " : len=" RLENGTH ",start=" RSTART > "/dev/tty";
  562. mstr=substr(matches2[i],RSTART,RLENGTH);
  563. mstr=substr(mstr,2,length(mstr)-1);
  564. if(debug) print "Comparing " CVERSION " and " mstr > "/dev/tty";
  565. if(cmpver(mstr,CVERSION)==1) {
  566. CVERSION=mstr;
  567. CFILE=matches2[i];
  568. hadmatch=1;
  569. }
  570. }
  571. # Print the matched file, or nothing if no matches!
  572. if(hadmatch) {
  573. print CFILE,CVERSION;
  574. }
  575. }'
  576. }
  577. if [[ $install -eq 1 ]]
  578. then
  579. xxdata="$(get_latest_match $matches)"
  580. install_file="$($print $xxdata | $awk '{print $1}')"
  581. install_version="$($print $xxdata | $awk '{print $2}'|sed 's/-/./g')"
  582. if [[ -z "$install_version" ]]
  583. then
  584. showscriptinfo
  585. logerror "No matching packages found." 4
  586. fi
  587. logmsg "Installing from file $install_file";
  588. fi
  589. ## HERE - install_file/version will be BUNDLE if BUNDLE set...
  590. if [[ -n "$BUNDLE" ]]
  591. then
  592. logmsg " [$install_file is a bundle]"
  593. logmsg " [Installing packages of pattern \"$ARG_PKG\" from bundle $BUNDLE version $install_version]"
  594. #########################################################
  595. # Now get a list of packages that will be considered #
  596. # for installation... #
  597. #########################################################
  598. flist="$(tar tf "$ARG_DEPOT/$install_file"| sort | uniq |
  599. $awk -v P="$ARG_PKG" 'BEGIN {last="";} /\.tarp$/ || /\.tarp\.gz$/ || /\.tarp\.Z$/ || /\/.tarp\.bz2$/ {if(match(substr($0,3),P)) {p=substr($0,3,index($0,",")-3); if(p!=last) {printf(" "); } else {printf("|");} printf("%s",substr($0,3));}}')"
  600. logmsg "Initial package list: $flist"
  601. #################################################################
  602. # This is the interesting bit ... we recursively call this #
  603. # program to check each file, and if suitable install it... #
  604. # We break down the list of packages into common names - since #
  605. # a bundle can actually have code for multiple architectures #
  606. # available... #
  607. #################################################################
  608. TMP_BUNDLE_DEPOT=$TARP_DB/bundle-$$.tmp
  609. mkdir $TMP_BUNDLE_DEPOT 2>/dev/null || {
  610. logerror "Unable to create temporary directory.";
  611. logerror "[Directory is $TMP_BUNDLE_DEPOT]" 22;
  612. }
  613. #################################################################
  614. # We actually extract everything - since we might have #
  615. # dependencies on other things in the bundle. #
  616. #################################################################
  617. logmsg "Extracting bundle contents to temporary directory."
  618. logmsg "[directory = $TMP_BUNDLE_DEPOT]"
  619. cwd=$PWD
  620. cd $TMP_BUNDLE_DEPOT
  621. tar xf $ARG_DEPOT/$install_file 2>/dev/null || {
  622. logerror "Unable to extract bundle contents." 23;
  623. }
  624. #################################################################
  625. # We now call tpinstall for each of the attempted sets of #
  626. # packages to install. #
  627. #################################################################
  628. export TMP_BUNDLE_DEPOT
  629. newilist=""
  630. for cinstall in $flist
  631. do
  632. tmatches="$(get_latest_match "$($print "$cinstall" | sed 's/\|/ /g')")"
  633. install_file="$($print $tmatches | $awk '{print $1}')"
  634. install_version="$($print $tmatches | $awk '{print $2}'|sed 's/-/./g')"
  635. install_pkg="$($print $install_file | $awk -v FS=, '{print $1}')"
  636. cmd="$_PRG2 -i -p $install_pkg -d $TMP_BUNDLE_DEPOT -l"
  637. ((ARG_VERBOSE)) && cmd="$cmd -v"
  638. [[ -n "$BUNDLE" ]] && cmd="$cmd -B $BUNDLE"
  639. logmsg "Installing $install_pkg."
  640. logmsg " Finding dependencies for $install_pkg [version $install_version]:"
  641. logmsg " $cmd"
  642. eval "$cmd" >> /tmp/tps-$$.errs 2>&1
  643. rc=$?
  644. [[ $rc = 99 ]] && {
  645. logmsg " Package installed at required version.";
  646. continue;
  647. }
  648. if [[ $rc != 0 ]]
  649. then
  650. logerror "Unable to find dependencies for $install_pkg - aborting"
  651. logerror "See file /tmp/tps-$$.errs for details."
  652. fi
  653. newilist="$newilist $cinstall"
  654. done
  655. logmsg "All dependencies are available - continuing."
  656. #################################################################
  657. # We now attempt to install the packages... #
  658. #################################################################
  659. [[ -f "/tmp/tps-$$.errs" ]] && rm -f "/tmp/tps-$$.errs"
  660. for cinstall in $newilist
  661. do
  662. tmatches="$(get_latest_match "$($print "$cinstall" | sed 's/\|/ /g')")"
  663. install_file="$($print $tmatches | $awk '{print $1}')"
  664. install_version="$($print $tmatches | $awk '{print $2}'|sed 's/-/./g')"
  665. install_pkg="$($print $install_file | $awk -v FS=, '{print $1}')"
  666. [[ -z "$install_file" ]] && continue
  667. cmd="$_PRG2 -i -p $install_pkg -d $TMP_BUNDLE_DEPOT -j 2 -B $BUNDLE"
  668. ((ARG_VERBOSE)) && cmd="$cmd -v"
  669. ((ARG_PREVIEW)) && cmd="$cmd -P"
  670. ((ARG_NOPERMS)) && cmd="$cmd -s"
  671. ((ARG_NOPERMS)) && cmd="$cmd -s"
  672. [[ -n "$ARG_ROOTDIR" ]] && cmd="$cmd -r $ARG_ROOTDIR"
  673. logmsg "Installation of $install_pkg [version $install_version]:"
  674. logmsg " $cmd"
  675. [[ ! -f /tmp/tps-$$.errs ]] && $print "" >/tmp/tps-$$.errs
  676. ll=$(wc -l < /tmp/tps-$$.errs)
  677. eval "$cmd" 2>&1 | tee -a /tmp/tps-$$.errs
  678. if [[ -n "$($awk -v LL=$ll 'NR>LL && /ERROR/ {print 1}' /tmp/tps-$$.errs)" ]]
  679. then
  680. cleanup
  681. logerror "Unable to install $install_pkg - aborting"
  682. logerror "See file /tmp/tps-$$.errs for details." 24
  683. fi
  684. done
  685. cleanup
  686. logmsg "Packages successfully installed - see /tmp/tps-$$.errs for details."
  687. exit 0
  688. fi
  689. [[ $ARG_LISTDEPS -eq 1 ]] && $print "V $install_version"
  690. #########################################################################
  691. # If we are about to commit a package, then we actually do quite #
  692. # little - we change the status file to "committed" and remove the #
  693. # saved_files sub-directory. #
  694. #########################################################################
  695. if [[ $commit -eq 1 ]]
  696. then
  697. if [[ ! -d $TARP_DB/$ARG_PKG ]]
  698. then
  699. showscriptinfo
  700. logerror "Package $ARG_PKG is not yet installed" 3
  701. fi
  702. #################################################################
  703. # Change the status to committed, assuming that it is #
  704. # currently set to installed. #
  705. #################################################################
  706. if [[ ! -f "$TARP_DB/$ARG_PKG/status" ]]
  707. then
  708. status="Unknown";
  709. else
  710. status="$(<$TARP_DB/$ARG_PKG/status)"
  711. fi
  712. if [[ "$status" != "installed" ]]
  713. then
  714. showscriptinfo
  715. logerror "Can not commit a package when in $status status" 6
  716. fi
  717. #################################################################
  718. # Now removed the saved_files sub-directory if it exists. #
  719. #################################################################
  720. if [[ -d "$TARP_DB/$ARG_PKG/saved_files" ]]
  721. then
  722. rm -rf "$TARP_DB/$ARG_PKG/saved_files"
  723. fi
  724. #################################################################
  725. # We now change the status to committed and remove the #
  726. # saved_files sub-directory. #
  727. #################################################################
  728. $print "committed" > /$TARP_DB/$ARG_PKG/status 2>/dev/null || {
  729. showscriptinfo;
  730. logerror "Unable to update package database - aborting" 7;
  731. }
  732. logmsg "Package $ARG_PKG successfully committed."
  733. exit 0
  734. fi
  735. #########################################################################
  736. # First step to install a package is to check to see if it is already #
  737. # installed and if so, make sure it is currently committed. #
  738. #########################################################################
  739. if [[ -z "$ARG_INBUNDLE" ]]
  740. then
  741. spec_dir=$ARG_PKG
  742. else
  743. spec_dir=$ARG_INBUNDLE.$ARG_PKG
  744. fi
  745. logmsg "Checking for $TARP_DB/$spec_dir"
  746. if [[ -d "$TARP_DB/$spec_dir" ]]
  747. then
  748. [[ -f "$TARP_DB/$spec_dir/status" ]] &&
  749. status="$(< $TARP_DB/$spec_dir/status)" ||
  750. status="Unknown";
  751. if [[ "$status" != "committed" ]]
  752. then
  753. showscriptinfo
  754. logerror "Package currently installed, but in state $status - not committed!" 8
  755. fi
  756. #################################################################
  757. # We need to get the version of the currently installed #
  758. # and ensure that the new version to install is greater, #
  759. # unless the force argument is specified. #
  760. #################################################################
  761. VERSION=$($awk -v FS=":" '/^VERSION:/ {print $2}' $TARP_DB/$spec_dir/spec)
  762. [[ -z "$VERSION" ]] && VERSION="0.0.0";
  763. #################################################################
  764. # Get 1 if the package to install is newer... #
  765. #################################################################
  766. isnewer=$($print "" | $awk -v IV="$VERSION" -v NV=$install_version '
  767. function cmpver(v1,v2,x1,x2) {
  768. split(v1,x1,/\./); split(v2,x2,/\./);
  769. if(x1[1]>x2[1]) return 1;
  770. if(x1[1]<x2[1]) return -1;
  771. if(x1[2]>x2[2]) return 1;
  772. if(x1[2]<x2[2]) return -1;
  773. if(x1[3]>x2[3]) return 1;
  774. if(x1[3]<x2[3]) return -1;
  775. return 0;
  776. }
  777. {print cmpver(NV,IV);exit;}')
  778. if [[ $isnewer -ne 1 && $ARG_FORCE -eq 0 ]]
  779. then
  780. showscriptinfo
  781. logwarn "Version selected for installation is not newer than currently installed version"
  782. exit 99
  783. fi
  784. typeset -u OVERWRITE
  785. OVERWRITE=$($awk -v FS=":" '/^OVERWRITE:/ {print $2}' $TARP_DB/$spec_dir/spec)
  786. [[ -z "$OVERWRITE" ]] && OVERWRITE="YES"
  787. if [[ "$OVERWRITE" = NO ]]
  788. then
  789. logerror "Package can not be overwritten - please remove old version first." 22
  790. fi
  791. fi
  792. #########################################################################
  793. # Ok, so the package is committed, and we have the correct version to #
  794. # install, so unpack the software in a temporary location. #
  795. #########################################################################
  796. TMPDIR="$TARP_DB/tpinstall-$$"
  797. mkdir -p $TMPDIR 2>/dev/null || {
  798. showscriptinfo;
  799. logerror "Unable to create temporary directory $TMPDIR" 23;
  800. }
  801. logmsg "Using temporary directory $TMPDIR"
  802. trap "cleanup $TMPDIR" 1 2 3 15 EXIT
  803. #########################################################################
  804. # Extract the spec file only first, to get the list of package #
  805. # dependencies. #
  806. #########################################################################
  807. cd $TMPDIR 2>/dev/null || {
  808. showscriptinfo;
  809. logerror "Unable to change to temporary directory to spool software!" 11;
  810. }
  811. #########################################################################
  812. # Indicate that the package is not yet installed, and also keep a #
  813. # install_list of files that should be removed if we back-out. #
  814. #########################################################################
  815. $print "broken" > status 2>/dev/null || {
  816. showscriptinfo;
  817. logerror "Unable to update package database - aborting" 7;
  818. }
  819. xcmd="$(print $ARG_DEPOT $install_file "./spec" | $awk '
  820. $2 ~ /.*\.tarp$/ {printf("tar xf %s/%s %s",$1,$2,$3);}
  821. $2 ~ /.*\.tarp\.gz$/ {printf("gunzip -c %s/%s | tar xf - %s",$1,$2,$3);}
  822. $2 ~ /.*\.tarp\.bz2$/ {printf("bunzip2 -c %s/%s | tar xf - %s",$1,$2,$3);}
  823. $2 ~ /.*\.tarp\.Z$/ {printf("zcat < %s/%s | tar xf - %s",$1,$2,$3);}')"
  824. eval "$xcmd >/dev/null 2>&1"
  825. rc=$?
  826. [[ $rc != 0 ]] && {
  827. showscriptinfo;
  828. logerror "An error occurred whilst extract .spec file - please check archive!" 66;
  829. }
  830. [[ ! -f spec ]] && {
  831. showscriptinfo;
  832. logerror "Invalid package file found - aborting!" 24;
  833. }
  834. #########################################################################
  835. # We get the list of dependencies, and call the dependency checker #
  836. # which will show information as follows: #
  837. # I:software,current,minver - Specified package is currently #
  838. # installed at level required. #
  839. # U:software,current,minver - Specified software is installed, but #
  840. # version is below minimum required. #
  841. # N:software,minver - New installation required, at least #
  842. # of the version specified. #
  843. # #
  844. # Dependency handling for bundles #
  845. # =============================== #
  846. # [1] If an a bundle then the dependency name strips off any bundle #
  847. # name and prefixes the current bundle name. #
  848. # #
  849. # This will change in a later release to ensure that dependencies #
  850. # for a package in a bundle can be found elsewhere (when depot #
  851. # searching is implemented). #
  852. # #
  853. #########################################################################
  854. deps=$($awk -v FS=: '/^DEPENDENCIES:/ {print $2}' spec)
  855. if [[ -n "$deps" ]]
  856. then
  857. logmsg "Checking package dependencies..."
  858. deps="$($print "$deps" | tr "|" " ")"
  859. TMPDIR2=$TMPDIR.2
  860. mkdir -p $TMPDIR2 || {
  861. showscriptinfo;
  862. logerror "Unable to make temporary directory $TMPDIR2" 25;
  863. }
  864. package_deps=""
  865. for cdep in $deps
  866. do
  867. cpkg=$($print "$cdep" | $awk -v FS=, '{print $1}')
  868. cver=$($print "$cdep" | $awk -v FS=, '{print $2}')
  869. if [[ ! -f "$TARP_DB/$cpkg/spec" ]]
  870. then
  871. package_deps="N $cpkg $cver\n$package_deps"
  872. else
  873. pcver=$($awk -v FS=: '/^VERSION:/ {print $2}' $TARP_DB/$cpkg/spec)
  874. isnewer=$($print "" | $awk -v IV="$cver" -v NV=$pcver '
  875. function cmpver(v1,v2,x1,x2) {
  876. split(v1,x1,/\./); split(v2,x2,/\./);
  877. if(x1[1]>x2[1]) return 1;
  878. if(x1[1]<x2[1]) return -1;
  879. if(x1[2]>x2[2]) return 1;
  880. if(x1[2]<x2[2]) return -1;
  881. if(x1[3]>x2[3]) return 1;
  882. if(x1[3]<x2[3]) return -1;
  883. return 0;
  884. }
  885. {print cmpver(NV,IV);exit;}')
  886. if [[ $isnewer -eq -1 ]]
  887. then
  888. package_deps="U $cpkg $pcver $cver\n$package_deps"
  889. else
  890. package_deps="I $cpkg $pcver $cver\n$package_deps"
  891. fi
  892. fi
  893. done
  894. rm -rf $TMPDIR2
  895. #################################################################
  896. # Foreach line that is not a I, then we get the package #
  897. # requirements for them (tail recursion...). #
  898. #################################################################
  899. tdeps=""
  900. $print "$package_deps" | while read ac ac_pkg v1 v2
  901. do
  902. [[ -z "$ac" ]] && continue
  903. [[ "$ac" = "I" ]] &&
  904. tdeps="$ac $ac_pkg $v1 $v2\n$tdeps" &&
  905. continue
  906. logmsg "Getting dependencies for $ac_pkg..."
  907. these="$($_PRG2 -i -d $ARG_DEPOT -p $ac_pkg -l 2>/dev/null)"
  908. RC=$?
  909. [[ $RC -ne 0 ]] &&
  910. tdeps="X $ac_pkg $v1 $v2\n$tdeps" &&
  911. continue
  912. these2="$($print "$these" | $awk 'NR>1')"
  913. v2="$($print "$these" | $awk 'NR==1 {print $2}')"
  914. logmsg "$ac $ac_pkg $v1 $v2"
  915. tdeps="$these2\n$ac $ac_pkg $v1 $v2\n$tdeps"
  916. done
  917. package_deps="$tdeps"
  918. else
  919. logmsg "No dependencies required for package."
  920. fi
  921. if [[ $ARG_LISTDEPS -eq 1 ]]
  922. then
  923. $print "$package_deps" | while read ac ac_pkg v1 v2
  924. do
  925. [[ -z "$ac" ]] && continue
  926. $print "$ac:$ac_pkg,$v1,$v2"
  927. done
  928. exit 0
  929. fi
  930. typeset -i dep_errors=0
  931. typeset -i dep_count=0
  932. had_deps=0
  933. install_list=""
  934. $print "$package_deps" | while read ac ac_pkg v1 v2
  935. do
  936. [[ -z "$ac" ]] && continue
  937. [[ $had_deps -eq 0 ]] && {
  938. [[ -n "$ARG_INBUNDLE" ]] &&
  939. logmsg "Package dependencies (via bundle $ARG_INBUNDLE):" ||
  940. logmsg "Package dependencies:" && had_deps=1;
  941. }
  942. logmsg " $ac_pkg"
  943. [[ "$ac" = "I" ]] &&
  944. logmsg " - already installed; $v1 >= $v2"
  945. [[ "$ac" = "U" ]] &&
  946. logmsg " + already installed, upgrade required; $v1 < $v2" &&
  947. let dep_count=dep_count+1 &&
  948. install_list="$install_list\n$ac_pkg $v2"
  949. if [[ "$ac" = "N" ]]
  950. then
  951. isnewer=$($print "" | $awk -v IV="$v2" -v NV=$v1 '
  952. function cmpver(v1,v2,x1,x2) {
  953. split(v1,x1,/\./); split(v2,x2,/\./);
  954. if(x1[1]>x2[1]) return 1;
  955. if(x1[1]<x2[1]) return -1;
  956. if(x1[2]>x2[2]) return 1;
  957. if(x1[2]<x2[2]) return -1;
  958. if(x1[3]>x2[3]) return 1;
  959. if(x1[3]<x2[3]) return -1;
  960. return 0;
  961. }
  962. {print cmpver(NV,IV);exit;}')
  963. if [[ $isnewer -ne 1 ]]
  964. then
  965. logmsg " + new install required; asked for $v1, depot version $v2"
  966. install_list="$install_list\n$ac_pkg $v2"
  967. let dep_count=dep_count+1
  968. else
  969. logmsg " ! new install required; asked for $v1, depot version $v2"
  970. let dep_errors=dep_errors+1
  971. fi
  972. fi
  973. [[ "$ac" = "X" ]] &&
  974. logmsg " ? install/upgraded required; $v2+ not in depot" &&
  975. let dep_errors=dep_errors+1
  976. done
  977. [[ $dep_errors -gt 0 && $ARG_NDEPS -eq 0 ]] && {
  978. showscriptinfo;
  979. [[ $dep_errors -gt 1 ]] &&
  980. logerror "$dep_errors missing dependencies, aborting" 30;
  981. [[ $dep_errors -eq 1 ]] &&
  982. logerror "$dep_errors missing dependency, aborting" 30;
  983. }
  984. [[ $dep_errors -gt 0 && $ARG_NDEPS -eq 1 ]] && {
  985. showscriptinfo;
  986. [[ $dep_errors -gt 1 ]] && logwarn "$dep_errors missing dependencies, aborting" 30;
  987. [[ $dep_errors -eq 1 ]] && logwarn "$dep_errors missing dependency, aborting" 30;
  988. }
  989. logmsg "Number of dependencies to install: $dep_count"
  990. if [[ $ARG_PREVIEW -eq 1 ]]
  991. then
  992. exit 0
  993. fi
  994. if [[ $dep_count -gt 0 ]]
  995. then
  996. if [[ $ARG_NODEPS -eq 1 ]]
  997. then
  998. logwarn "-x flag used, required dependencies will not be installed!"
  999. else
  1000. $print "$install_list" | while read pkg ver
  1001. do
  1002. [[ -z "$pkg" ]] && continue
  1003. logmsg "Installing dependency $pkg (version $ver):"
  1004. logfile="/tmp/tpinstall-$$.$pkg"
  1005. cmd="$_PRG2 -i -d $ARG_DEPOT -p $pkg -v -r $ARG_ROOTDIR"
  1006. [[ $ARG_NOCOMMIT -eq 1 ]] && cmd="$cmd -n"
  1007. [[ $ARG_NOPERMS -eq 1 ]] && cmd="$cmd -s"
  1008. [[ -n "$ARG_INBUNDLE" ]] && cmd="$cmd -B $ARG_INBUNDLE"
  1009. logmsg "$cmd"
  1010. eval "$cmd >$logfile 2>&1"
  1011. RC=$?
  1012. [[ $RC -ne 0 ]] && {
  1013. showscriptinfo;
  1014. logerror "Unable to install dependency $pkg - see $logfile for details" 31;
  1015. }
  1016. logmsg "Package $pkg successfully installed (log=$logfile)"
  1017. done
  1018. fi
  1019. fi
  1020. xcmd="$(print $ARG_DEPOT $install_file "" | $awk '
  1021. $2 ~ /.*\.tarp$/ {printf("tar xf %s/%s %s",$1,$2,$3);}
  1022. $2 ~ /.*\.tarp\.gz$/ {printf("gunzip -c %s/%s | tar xf - %s",$1,$2,$3);}
  1023. $2 ~ /.*\.tarp\.bz2$/ {printf("bunzip2 -c %s/%s | tar xf - %s",$1,$2,$3);}
  1024. $2 ~ /.*\.tarp\.Z$/ {printf("zcat < %s/%s | tar xf - %s",$1,$2,$3);}')"
  1025. logmsg "Beginning package extract to $TMPDIR..."
  1026. eval $xcmd >/tmp/tpxcmd.$$ 2>&1
  1027. if [[ $? -ne 0 ]]
  1028. then
  1029. cd -
  1030. showscriptinfo
  1031. logerror "Unable to extract files to temporary directory:"
  1032. logerrorfile /tmp/tpxcmd.$$
  1033. exit 13
  1034. fi
  1035. rm -f /tmp/tpxcmd.$$
  1036. #########################################################################
  1037. # If a checkinstall script is present then we execute it - and if #
  1038. # we do not get a zero return code then the installation of the #
  1039. # package is quietly ignored. #
  1040. #########################################################################
  1041. [[ -f ./checkinstall ]] && chmod +x ./checkinstall 2>/dev/null
  1042. if [[ -x ./checkinstall ]]
  1043. then
  1044. ./checkinstall >/dev/null 2>&1
  1045. r=$?
  1046. [[ $r -gt 0 ]] &&
  1047. logmsg "Checkinstall - package not suitable" &&
  1048. exit 77
  1049. fi
  1050. logmsg "Package extraction completed successfully."
  1051. mkdir saved_files 2>/dev/null || {
  1052. showscriptinfo;
  1053. logerror "Unable to create temporary directory to spool software!" 14;
  1054. }
  1055. $print "$ARG_ROOTDIR" >rootdir 2>/dev/null || {
  1056. showscriptinfo;
  1057. logerror "Unable to write new root directory file" 32;
  1058. }
  1059. #########################################################################
  1060. # If we have a preinstall script then run it now, setting the #
  1061. # PACKAGE and VERSION environment variables first. #
  1062. #########################################################################
  1063. export BUNDLE=$ARG_INBUNDLE
  1064. export PACKAGE=$ARG_PKG
  1065. export VERSION
  1066. prelogoutput=/tmp/tpinstall-pre-$ARG_PKG-$$.stdout
  1067. prelogerror=/tmp/tpinstall-pre-$ARG_PKG-$$.stderr
  1068. [[ -f ./preinstall ]] && chmod +x ./preinstall 2>/dev/null
  1069. if [[ -x ./preinstall ]]
  1070. then
  1071. logmsg "Running pre-install script..."
  1072. ./preinstall >$prelogoutput 2>$prelogerror
  1073. r=$?
  1074. [[ $r -gt 2 ]] && {
  1075. showscriptinfo;
  1076. logerror "Return code $r from pre-install script - aborting" 20;
  1077. }
  1078. [[ $r -eq 1 ]] && {
  1079. [[ $ARG_FORCE -eq 1 ]] &&
  1080. logwarn "Return code 1 from pre-install script." || {
  1081. showscriptinfo;
  1082. logerror "Return code 1 from pre-install script." 21;
  1083. }
  1084. }
  1085. [[ $r -eq 0 ]] && logmsg "Pre-install script completed successfully."
  1086. fi
  1087. #########################################################################
  1088. # Now create backup copies of all files that will be over-written. #
  1089. #########################################################################
  1090. logmsg "Saving files that will be overwritten..."
  1091. typeset -i saved_count=0
  1092. typeset -i saved_size=0
  1093. xcmd="$(print $ARG_DEPOT $install_file "" | $awk '
  1094. $2 ~ /.*\.tarp$/ {printf("tar tf %s/%s %s",$1,$2,$3);}
  1095. $2 ~ /.*\.tarp\.gz$/ {printf("gunzip -c %s/%s | tar tf - %s",$1,$2,$3);}
  1096. $2 ~ /.*\.tarp\.bz2$/ {printf("bunzip2 -c %s/%s | tar tf - %s",$1,$2,$3);}
  1097. $2 ~ /.*\.tarp\.Z$/ {printf("zcat < %s/%s | tar tf - %s",$1,$2,$3);}')"
  1098. #################################################################
  1099. # Before doing anything really - double check the contents of #
  1100. # the archive and abort if necessary. #
  1101. #################################################################
  1102. eval "$xcmd 2>/dev/null >/dev/null"
  1103. rc=$?
  1104. [[ $rc != 0 ]] && {
  1105. showscriptinfo;
  1106. logerror "An error occurred whilst scanning package contents - please check archive!" 66;
  1107. }
  1108. for fp in $(eval "$xcmd 2>/dev/null" |
  1109. egrep -v '\./spec|\./postinstall|\./preinstall|\./checkinstall|\.preremove|\./postremove|\./postinstall\.perms' | $awk 'substr($0,length($0)) != "/" {print substr($0,2);}')
  1110. do
  1111. if [[ -f "$ARG_ROOTDIR$fp" ]]
  1112. then
  1113. (cd $ARG_ROOTDIR && tar cpf - .$fp 2>/dev/null ) |
  1114. (cd saved_files && tar xpf - 2>/dev/null ) || {
  1115. showscriptinfo;
  1116. logerror "Out of space or permissions error whilst storing backup files" 15;
  1117. }
  1118. let saved_count=saved_count+1
  1119. fi
  1120. done
  1121. if [[ $saved_count -gt 0 ]]
  1122. then
  1123. saved_size=$(du -sk saved_files | $awk '{print $1}')
  1124. logmsg "Files Saved: $saved_count ($saved_size Kb)"
  1125. else
  1126. logmsg "No files required saving."
  1127. fi
  1128. #########################################################################
  1129. # Now we actually move the real files into place, creating a cksums #
  1130. # file once the files have been installed. #
  1131. #########################################################################
  1132. typeset -i installed_count=0
  1133. typeset -i installed_size=0
  1134. logmsg "Installing package files..."
  1135. #########################################################################
  1136. # Now we are about to overwrite files, we add a re-install call #
  1137. # as part of the trap command. #
  1138. #########################################################################
  1139. $print "broken2" > status 2>/dev/null || {
  1140. showscriptinfo;
  1141. logerror "Unable to update package database - aborting" 7;
  1142. }
  1143. trap "cleanup $TMPDIR; logmsg 'Cleaning up directory $TMPDIR'; rm -rf $TMPDIR" EXIT
  1144. cd $TMPDIR 2>/dev/null || logerror "Unable to change to spool directory" 33
  1145. volatile_ext=$($awk -v FS=: '$1 == "VOLATILE_EXT" {gsub(/,/," ",$2); print $2}' spec)
  1146. if [[ -n "$volatile_ext" ]]
  1147. then
  1148. logmsg "Volatile file extensions defined as : $volatile_ext"
  1149. fi
  1150. find . \( -name saved_files -prune \) -o \( -type f -print \) | egrep -v '\./spec|\./postinstall|\./preinstall|\./checkinstall|\.preremove|\./postremove|\./postinstall\.perms|\./rootdir|\./status' >/tmp/tpinstall-$$.2
  1151. #########################################################################
  1152. # Always copy files rather than use cpio now, since more compatible #
  1153. # across different server types. #
  1154. #########################################################################
  1155. for f1 in $(cat /tmp/tpinstall-$$.2)
  1156. do
  1157. [[ ! -d $(basename $ARG_ROOTDIR/$f1) ]] && {
  1158. mkdir -p $(dirname $ARG_ROOTDIR/$f1) || {
  1159. logerror "Unable to perform the following operation:"
  1160. logerror "mkdir -p $(dirname $ARG_ROOTDIR/$f1)"
  1161. rm -f /tmp/tpinstall-$$.2 /tmp/tpinstall-$$
  1162. exit 21;
  1163. }
  1164. }
  1165. cp -f $f1 $ARG_ROOTDIR/$f1 2>>/tmp/tpinstall-$$ || {
  1166. showscriptinfo
  1167. logerror "Error occured whilst attempting to install $ARG_PKG"
  1168. logerror "Unable to perform the following operation:"
  1169. logerror "cp -f $f1 $ARG_ROOTDIR/$f1"
  1170. rm -f /tmp/tpinstall-$$.2 /tmp/tpinstall-$$
  1171. exit 16;
  1172. }
  1173. done
  1174. c1=$(wc -l < /tmp/tpinstall-$$)
  1175. c2=$(wc -l < /tmp/tpinstall-$$.2)
  1176. installed_count=$(($c2 - $c1))
  1177. rm -f /tmp/tpinstall-$$
  1178. mv /tmp/tpinstall-$$.2 /tmp/tpinstall-$$
  1179. [[ "$OS" = "Linux" ]] && cksum=md5sum || cksum=cksum
  1180. for cfile in $(grep -vi blocks /tmp/tpinstall-$$)
  1181. do
  1182. if [[ -n "$volatile_ext" ]]
  1183. then
  1184. this_ext=${cfile##*.}
  1185. if [[ "$this_ext" != "$cfile" ]]
  1186. then
  1187. found=0
  1188. for cext in $volatile_ext
  1189. do
  1190. [[ "$cext" = "$this_ext" ]] && {
  1191. $print "$cfile|V" >>cksums;
  1192. found=1;
  1193. break;
  1194. }
  1195. done
  1196. [[ $found -eq 1 ]] && continue
  1197. fi
  1198. fi
  1199. mc=$($cksum $cfile|$awk '{print $1}')
  1200. $print "$cfile|$mc" >>cksums
  1201. done
  1202. [[ -f /tmp/tpinstall-$$ ]] && rm -f /tmp/tpinstall-$$
  1203. logmsg "Files installed: $installed_count"
  1204. #########################################################################
  1205. # Now the files have been installed, and so we create the status #
  1206. # file and remove an older copy of this package, if it exists, and #
  1207. # finally rename this directory. #
  1208. #########################################################################
  1209. $print "installed" >status 2>/dev/null || {
  1210. showscriptinfo;
  1211. logerror "Unable go write to status file!";
  1212. logerror "Command attempted: $print installed >$PWD/status" 17;
  1213. }
  1214. [[ -d $TARP_DB/$spec_dir ]] && {
  1215. mv $TARP_DB/$spec_dir $TARP_DB/$spec_dir.tmp || {
  1216. showscriptinfo;
  1217. logerror "Unable to rename old package status directory";
  1218. logerror "Command attempted: mv $TARP_DB/$spec_dir $TARP_DB/$spec_dir.tmp" 18;
  1219. }
  1220. }
  1221. mv -f $TMPDIR $TARP_DB/$spec_dir
  1222. [[ ! -d $TARP_DB/$spec_dir ]] && {
  1223. showscriptinfo;
  1224. logerror "Unable to rename temporary status directory" 19;
  1225. }
  1226. #########################################################################
  1227. # If we have a postinstall script then run it now, setting the #
  1228. # PACKAGE and VERSION environment variables first. #
  1229. #########################################################################
  1230. export PACKAGE=$ARG_PKG
  1231. export VERSION
  1232. cd $TARP_DB/$spec_dir
  1233. if [[ $ARG_NOPERMS -eq 1 ]]
  1234. then
  1235. logwarn "Not setting package permissions."
  1236. else
  1237. [[ -f ./postinstall.perms ]] && chmod +x ./postinstall.perms 2>/dev/null
  1238. if [[ -x ./postinstall.perms ]]
  1239. then
  1240. logmsg "Setting Correct package permissions + ownerships..."
  1241. if [[ "$(id | $awk -v FS="[()]+" '{print $2}')" != root ]]
  1242. then
  1243. logwarn "Not changing owner/group info - not running as root."
  1244. cd $ARG_ROOTDIR &&
  1245. sed 's/chown.*//g' < $TARP_DB/$spec_dir/postinstall.perms | /bin/sh 2>/tmp/tpinstall-$$.3 2>&1
  1246. else
  1247. cd $ARG_ROOTDIR &&
  1248. $TARP_DB/$spec_dir/postinstall.perms 2>/tmp/tpinstall-$$.3 2>&1
  1249. fi
  1250. #################################################################
  1251. # Issue a warning if we've any output from attempting to set #
  1252. # the permissions. #
  1253. #################################################################
  1254. if [[ -s /tmp/tpinstall-$$.3 ]]
  1255. then
  1256. logwarn "The following errors occured whilst setting permissions:"
  1257. logwarnfile /tmp/tpinstall-$$.3
  1258. fi
  1259. rm -f /tmp/tpinstall-$$.3
  1260. fi
  1261. fi
  1262. [[ -f ./postinstall ]] && chmod +x ./postinstall 2>/dev/null
  1263. postlogoutput=/tmp/tpinstall-post-$ARG_PKG-$$.stdout
  1264. postlogerror=/tmp/tpinstall-post-$ARG_PKG-$$.stderr
  1265. cd $TARP_DB/$spec_dir
  1266. if [[ -x ./postinstall ]]
  1267. then
  1268. logmsg "Running post-install script..."
  1269. ./postinstall >$postlogoutput 2>$postlogerror
  1270. r=$?
  1271. [[ $r -gt 0 ]] && {
  1272. logwarn "Return code $r from post-install script.";
  1273. }
  1274. logmsg "Post-install script completed successfully."
  1275. fi
  1276. #########################################################################
  1277. # Now we remove everything from the directory that we do not expect #
  1278. # to need. #
  1279. #########################################################################
  1280. logmsg "Removing spooled package files..."
  1281. cd $TARP_DB/$spec_dir || {
  1282. showscriptinfo;
  1283. logerror "Unable to change to spool directory" 33;
  1284. }
  1285. for cfile in $(ls 2>/dev/null)
  1286. do
  1287. [[ "$x" = "." || "$x" = ".." ]] && continue
  1288. [[ "$x" = "preinstall" || "$x" = "postinstall" ]] && continue
  1289. [[ "$x" = "preremove" || "$x" = "postremove" ]] && continue
  1290. [[ "$x" = "saved_files" || "$x" = "cksums" ]] && continue
  1291. [[ "$x" = "spec" || "$x" = "status" ]] && continue
  1292. [[ "$x" = "checkinstall" ]] && continue
  1293. [[ "$x" = "postinstall.perms" || "$x" = "rootdir" ]] && continue
  1294. rm -rf $x 2>/dev/null
  1295. done
  1296. #########################################################################
  1297. # Indicate the package is installed, but not currently commited. #
  1298. #########################################################################
  1299. $print "installed" > /$TARP_DB/$spec_dir/status 2>/dev/null || {
  1300. showscriptinfo
  1301. logerror "Unable to update package database - aborting" 7;
  1302. }
  1303. logmsg "Package $ARG_PKG installed successfully."
  1304. #########################################################################
  1305. # We if have installed from a bundle then we copy across the #
  1306. # bundle information to a directory BUNDLE:name and in the name we #
  1307. # currently copy across the spec file contents... #
  1308. #########################################################################
  1309. if [[ -n "$ARG_INBUNDLE" ]]
  1310. then
  1311. if [[ ! -f "$ARG_DEPOT/spec" ]]
  1312. then
  1313. logwarn "Unable to copy bundle files - no bundle information"
  1314. logwarn "will be included, though packages will be installed."
  1315. else
  1316. mkdir "$TARP_DB/BUNDLE:$ARG_INBUNDLE" 2>/dev/null
  1317. cp -f $ARG_DEPOT/spec "$TARP_DB/BUNDLE:$ARG_INBUNDLE/spec" 2>/dev/null || {
  1318. logwarn "Unable to copy bundle files - no bundle information";
  1319. logwarn "will be included, though packages will be installed.";
  1320. }
  1321. fi
  1322. fi
  1323. [[ $ARG_NOCOMMIT -eq 1 ]] && {
  1324. showscriptinfo; exit 0;
  1325. }
  1326. #########################################################################
  1327. # Now removed the saved_files sub-directory if it exists. #
  1328. #########################################################################
  1329. if [[ -d "$TARP_DB/$spec_dir/saved_files" ]]
  1330. then
  1331. rm -rf "$TARP_DB/$spec_dir/saved_files"
  1332. fi
  1333. #################################################################
  1334. # We now change the status to committed and remove the #
  1335. # saved_files sub-directory. #
  1336. #################################################################
  1337. $print "committed" > /$TARP_DB/$spec_dir/status 2>/dev/null || {
  1338. showscriptinfo;
  1339. logerror "Unable to update package database - aborting" 7;
  1340. }
  1341. showscriptinfo;
  1342. logmsg "Package $ARG_PKG successfully committed."
  1343. exit 0