############################################################################### ## Command-line flags show_help() { echo "Command-line flags:" echo "/ --unix-style : install as Unix-style" echo "\ --in-place : install in-place (not Unix-style)" echo " --dest : install to " echo " --create-dir : create destination for Unix-style if it does not exist" echo " --create-links : create links in for in-place install" echo " -h, --help : show this help" } where="" unixstyle="" accept_dirs="" SYSDIR="" SYSDIR_set="" while test $# -gt 0 ; do case "$1" in -h | --help) show_help exit 0 ;; --unix-style) if test "$unixstyle" != "" ; then echo "conflicting or redundant flag: --unix-style" exit 1 fi unixstyle="Y" accept_dirs="Y" shift ;; --in-place) if test "$unixstyle" != "" ; then echo "conflicting or redundant flag: --in-place" exit 1 fi unixstyle="N" SYSDIR_set="Y" shift ;; --dest) shift if test $# -lt 1 ; then echo "missing path for --dest" exit 1 fi where="$1" if test "$where" = "" ; then echo "empty path for --dest" exit 1 fi shift ;; --create-dir) if test "$create_dir" != "" ; then echo "redundant flag: --create-dir" exit 1 fi create_dir="Y" shift ;; --create-links) if test "$SYSDIR" != "" ; then echo "redundant flag: --create-links" exit 1 fi shift if test $# -lt 1 ; then echo "missing path for --create-links" exit 1 fi SYSDIR="$1" SYSDIR_set="Y" if test "$SYSDIR" = "" ; then echo "empty path for --create-links" exit 1 fi shift ;; *) echo "unrecognized command-line argument: $1" exit 1 ;; esac done ############################################################################### ## Utilities PATH=/usr/bin:/bin if test "x`echo -n`" = "x-n"; then echon() { /bin/echo "$*\c"; } else echon() { echo -n "$*"; } fi rm_on_abort="" failwith() { err="Error: " if test "x$1" = "x-noerror"; then err=""; shift; fi echo "$err$*" 1>&2 if test ! "x$rm_on_abort" = "x" && test -e "$rm_on_abort"; then echon " (Removing installation files in $rm_on_abort)" "$rm" -rf "$rm_on_abort" echo "" fi exit 1 } # intentional aborts abort() { failwith -noerror "Aborting installation."; } # unexpected exits exithandler() { echo ""; failwith "Aborting..."; } trap exithandler 2 3 9 15 lookfor() { saved_IFS="${IFS}" IFS=":" for dir in $PATH; do if test -x "$dir/$1"; then eval "$1=$dir/$1" IFS="$saved_IFS" return fi done IFS="$saved_IFS" failwith "could not find \"$1\"." } lookfor rm lookfor ls lookfor ln lookfor tail lookfor cksum lookfor tar lookfor gunzip lookfor mkdir lookfor basename lookfor dirname # substitute env vars and tildes expand_path_var() { eval "expanded_val=\"\$$1\"" first_part="${expanded_val%%/*}" if [ "x$first_part" = "x$expanded_val" ]; then rest_parts="" else rest_parts="/${expanded_val#*/}" fi case "x$first_part" in x*" "* ) ;; x~* ) expanded_val="`eval \"echo $first_part\"`$rest_parts" ;; esac eval "$1=\"$expanded_val\"" } # Need this to make new `tail' respect old-style command-line arguments. Can't # use `tail -n #' because some old tails won't know what to do with that. _POSIX2_VERSION=199209 export _POSIX2_VERSION origwd="`pwd`" installer_file="$0" cat_installer() { oldwd="`pwd`"; cd "$origwd" "$tail" +"$BINSTARTLINE" "$installer_file" cd "$oldwd" } echo "This program will extract and install $DISTNAME." echo "" echo "Note: the required diskspace for this installation is $ORIGSIZE." echo "" ############################################################################### ## What kind of installation? if test "$unixstyle" = ""; then echo "Do you want a Unix-style distribution?" echo " In this distribution mode files go into different directories according" echo " to Unix conventions. A \"racket-uninstall\" script will be generated" echo " to be used when you want to remove the installation. If you say 'no'," echo " the whole Racket directory is kept in a single installation directory" echo " (movable and erasable), possibly with external links into it -- this is" echo " often more convenient, especially if you want to install multiple" echo " versions or keep it in your home directory." if test ! "x$RELEASED" = "xyes"; then echo "*** This is a non-release build: such a Unix-style distribution is NOT" echo "*** recommended, because it cannot be used to install multiple versions" echo "*** in the default location." fi unixstyle="x" while test "$unixstyle" = "x"; do echon "Enter yes/no (default: no) > " read unixstyle case "$unixstyle" in [yY]* ) unixstyle="Y" ;; [nN]* ) unixstyle="N" ;; "" ) unixstyle="N" ;; * ) unixstyle="x" ;; esac done echo "" fi ############################################################################### ## Where do you want it? ## sets $where to the location: target path for wholedir, prefix for unixstyle if test "$where" = ""; then if test "$unixstyle" = "Y"; then echo "Where do you want to base your installation of $DISTNAME?" echo " (If you've done such an installation in the past, either" echo " enter the same directory, or run 'racket-uninstall' manually.)" TARGET1="..." else echo "Where do you want to install the \"$TARGET\" directory tree?" TARGET1="$TARGET" fi echo " 1 - /usr/$TARGET1 [default]" echo " 2 - /usr/local/$TARGET1" echo " 3 - ~/$TARGET1 ($HOME/$TARGET1)" echo " 4 - ./$TARGET1 (here)" if test "$unixstyle" = "Y"; then echo " Or enter a different directory prefix to install in." else echo " Or enter a different \"racket\" directory to install in." fi echon "> " read where # numeric choice (make "." and "./" synonym for 4) if test "$unixstyle" = "Y"; then TARGET1="" else TARGET1="/$TARGET"; fi case "x$where" in x | x1 ) where="/usr$TARGET1" ;; x2 ) where="/usr/local${TARGET1}" ;; x3 ) where="${HOME}${TARGET1}" ;; x4 | x. | x./ ) where="`pwd`${TARGET1}" ;; * ) expand_path_var where ;; esac fi ############################################################################### ## Default system directories prefixed by $1, mimic configure behavior ## used for unixstyle targets and for wholedir links set_dirs() { # unixstyle: uses all of these # wholedir: uses only bindir, mandir, and appsdir, no need for the others bindir="$1/bin" libdir="$1/lib" incrktdir="$1/include/$TARGET" librktdir="$1/lib/$TARGET" sharerktdir="$1/share/$TARGET" configdir="$1/etc/$TARGET" appsdir="$1/share/applications" has_share="N" if test -d "$1/share"; then has_share="Y"; fi if test "$has_share" = "N" && test -d "$1/doc"; then docdir="$1/doc/$TARGET" else docdir="$1/share/$TARGET/doc" fi if test "$has_share" = "N" && test -d "$1/man"; then mandir="$1/man" else mandir="$1/share/man" fi } ############################################################################### ## Integrity check and unpack into $1 ## also sets $INSTDIR to the directory in its canonical form unpack_installation() { T="$1" # integrity check echo "" echon "Checking the integrity of the binary archive... " SUM="`cat_installer | \"$cksum\"`" || failwith "problems running cksum." SUM="`set $SUM; echo $1`" test "$BINSUM" = "$SUM" || failwith "bad CRC checksum." echo "ok." # test that the target does not exists here="N" if test -d "$T" || test -f "$T"; then if test -d "$T" && test -x "$T"; then # use the real name, so "/foo/.." shows as an explicit "/" oldwd="`pwd`"; cd "$T"; T="`pwd`"; cd "$oldwd" fi if test -f "$T"; then echon "\"$T\" exists (as a file)" elif test ! "`pwd`" = "$T"; then echon "\"$T\" exists" else here="Y"; echon "\"$T\" is where you ran the installer from" fi echon ", delete? " read R case "$R" in [yY]* ) echon "Deleting old \"$T\"... " "$rm" -rf "$T" || failwith "could not delete \"$T\"." echo "done." ;; * ) abort ;; esac fi # unpack rm_on_abort="$T" "$mkdir" -p "$T" || failwith "could not create directory: $T" if test "$here" = "Y"; then cd "$T"; INSTDIR="$T" echo "*** Note: your original directory was deleted, so you will need" echo "*** to 'cd' back into it when the installer is done, otherwise" echo "*** it will look like you have an empty directory." sleep 1 else oldwd="`pwd`"; cd "$T"; INSTDIR="`pwd`"; cd "$oldwd" fi rm_on_abort="$INSTDIR" echo "Unpacking into \"$INSTDIR\" (Ctrl+C to abort)..." cat_installer | "$gunzip" -c \ | { cd "$INSTDIR" "$tar" xf - || failwith "problems during unpacking of binary archive." } test -d "$INSTDIR/collects" \ || failwith "unpack failed (could not find \"$T/collects\")." echo "Done." } ############################################################################### ## Whole-directory installations wholedir_install() { unpack_installation "$where" rm_on_abort="" if test "$SYSDIR_set" != "Y"; then echo "" echo "If you want to install new system links within the \"bin\", \"man\"" echo " and \"share/applications\" subdirectories of a common directory prefix" echo " (for example, \"/usr/local\") then enter the prefix of an existing" echo " directory that you want to use. This might overwrite existing symlinks," echo " but not files." echon "(default: skip links) > " read SYSDIR fi if test "x$SYSDIR" = "x"; then : elif test ! -d "$SYSDIR"; then echo "\"$SYSDIR\" does not exist, skipping links." elif test ! -x "$SYSDIR" || test ! -w "$SYSDIR"; then echo "\"$SYSDIR\" is not writable, skipping links." else oldwd="`pwd`"; cd "$SYSDIR"; SYSDIR="`pwd`"; cd "$oldwd" set_dirs "$SYSDIR" install_links() { # tgtdir(absolute) srcdir(relative to INSTDIR) if ! test -d "$1"; then echo "\"$1\" does not exist, skipping." elif ! test -x "$1" || ! test -w "$1"; then echo "\"$1\" is not writable, skipping" else echo "Installing links in \"$1\"..." printsep=" " cd "$1" for x in `cd "$INSTDIR/$2"; ls`; do echon "${printsep}$x"; printsep=", " if test -h "$x"; then rm -f "$x"; fi if test -d "$x" || test -f "$x"; then echon " skipped (non-link exists)" elif ! "$ln" -s "$INSTDIR/$2/$x" "$x"; then echon " skipped (symlink failed)" fi done echo ""; echo " done." fi } install_links "$bindir" "bin" install_links "$mandir/man1" "man/man1" install_links "$appsdir" "share/applications" fi } ############################################################################### ## Unix-style installations dir_createable() { tdir="`\"$dirname\" \"$1\"`" if test -d "$tdir" && test -x "$tdir" && test -w "$tdir"; then return 0 elif test "$tdir" = "/"; then return 1 else dir_createable "$tdir"; fi } show_dir_var() { if test -f "$2"; then status="error: not a directory!"; err="Y" elif test ! -d "$2"; then if dir_createable "$2"; then status="will be created" else status="error: not writable!"; err="Y"; fi elif test ! -w "$2"; then status="error: not writable!"; err="Y" else status="exists" fi echo " $1 $2 ($status)" } unixstyle_install() { if test -f "$where"; then failwith "The entered base directory exists as a file: $where" elif test ! -d "$where"; then echo "Base directory does not exist: $where" if test "$create_dir" != "Y"; then echon " should I create it? (default: yes) " read R; case "$R" in [nN]* ) abort ;; esac fi "$mkdir" -p "$where" || failwith "could not create directory: $where" elif test ! -w "$where"; then failwith "The entered base directory is not writable: $where" fi cd "$where" || failwith "Base directory does not exist: $where" where="`pwd`"; cd "$origwd" set_dirs "$where" # loop for possible changes done="N"; retry="N" if test "$accept_dirs" = "Y" ; then done="Y"; fi while test ! "$done" = "Y" || test "x$err" = "xY" ; do err="N" if test "$retry" = "N"; then echo "" echo "Target Directories:" show_dir_var "[e] Executables " "$bindir" show_dir_var "[o] Libraries " "$librktdir" show_dir_var "[s] Shared files " "$sharerktdir" show_dir_var "[c] Configuration " "$configdir" show_dir_var "[d] Documentation " "$docdir" show_dir_var "[a] .desktop files" "$appsdir" show_dir_var "[m] Man Pages " "$mandir" show_dir_var "[l] C Libraries " "$libdir" show_dir_var "[h] C headers " "$incrktdir" echo "Enter a letter to change an entry, or enter to continue." fi retry="N" echon "> "; read change_what read_dir() { echon "New directory (absolute or relative to $where): "; read new_dir expand_path_var new_dir case "$new_dir" in "/"* ) eval "$1=\"$new_dir\"" ;; * ) eval "$1=\"$where/$new_dir\"" ;; esac } case "$change_what" in [eE]* ) read_dir bindir ;; [dD]* ) read_dir docdir ;; [lL]* ) read_dir libdir ;; [hH]* ) read_dir incrktdir ;; [oO]* ) read_dir librktdir ;; [sS]* ) read_dir sharerktdir ;; [cC]* ) read_dir configdir ;; [aA]* ) read_dir appsdir ;; [mM]* ) read_dir mandir ;; "" ) if test "$err" = "N"; then done="Y" else echo "*** Please fix erroneous paths to proceed"; fi ;; * ) retry="Y" ;; esac done if test -x "$bindir/racket-uninstall"; then echo "" echo "A previous Racket uninstaller is found at" echo " \"$bindir/racket-uninstall\"," echon " should I run it? (default: yes) " read R case "$R" in [nN]* ) abort ;; * ) echon " running uninstaller..." "$bindir/racket-uninstall" || failwith "problems during uninstall" echo " done." ;; esac fi tmp="$where/$TARGET-tmp-install" if test -f "$tmp" || test -d "$tmp"; then echo "\"$tmp\" already exists (needed for the installation)," echon " ok to remove it? " read R; case "$R" in [yY]* ) "$rm" -rf "$tmp" ;; * ) abort ;; esac fi unpack_installation "$tmp" cd "$where" "$tmp/bin/racket" "$tmp/collects/setup/unixstyle-install.rkt" \ "move" "$tmp" "$bindir" "$sharerktdir/collects" "$docdir" "$libdir" \ "$incrktdir" "$librktdir" "$sharerktdir" "$configdir" "$appsdir" "$mandir" \ || failwith "installation failed" } ############################################################################### ## Run the right installer now if test "$unixstyle" = "Y"; then unixstyle_install; else wholedir_install; fi echo "" echo "Installation complete." exit ========== tar.gz file follows ==========