From 601c90541d05eb5e49f8d049a01779669b7423b3 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 18 Jul 2012 22:25:02 -0400 Subject: [PATCH] Make it possible to use "~" or "~user" in the installer. I've looked for a while, and it seems that there is no easy way to do this, not even in bash, and worse with /bin/sh. So this is kind of resorting to a simple parsing of the input, and using `eval' if it starts with a tilde. Note the hack of not doing that when there is a space, otherwise the `eval' thing will silently ignore it. This hack means that it's easy to get into a mess if quotes are used after a tilde, but that was already the case with the use of `eval' to handle environment variables. It's not a real security issue, however, since we're talking about a user who can just run any command anyway. Also including a test file for the expansion functionality. If anyone wants to improve this code, making the tests pass would reveal the tricky issues. [FWIW, I've asked on the #bash channel, and the only serious suggestion was getting the paths as command-line arguments. This will, however, defeat the point of being newbie friendly...] Closes PR 12893. (cherry picked from commit 0814fd5fb5f660bc9698f21445976902317291d1) --- .../build/unix-installer/installer-header | 21 +++++++-- .../build/unix-installer/test-expand-path-var | 47 +++++++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100755 collects/meta/build/unix-installer/test-expand-path-var diff --git a/collects/meta/build/unix-installer/installer-header b/collects/meta/build/unix-installer/installer-header index 3edd4f7c4d..621321515f 100644 --- a/collects/meta/build/unix-installer/installer-header +++ b/collects/meta/build/unix-installer/installer-header @@ -54,6 +54,22 @@ 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 @@ -133,11 +149,9 @@ case "x$where" in x2 ) where="/usr/local${TARGET1}" ;; x3 ) where="${HOME}${TARGET1}" ;; x4 | x. | x./ ) where="`pwd`${TARGET1}" ;; + * ) expand_path_var where ;; esac -# substitute env vars and tildes -where="`eval \"echo \\\"$where\\\"\"`" - ############################################################################### ## Default system directories prefixed by $1, mimic configure behavior ## used for unixstyle targets and for wholedir links @@ -332,6 +346,7 @@ unixstyle_install() { 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\"" ;; diff --git a/collects/meta/build/unix-installer/test-expand-path-var b/collects/meta/build/unix-installer/test-expand-path-var new file mode 100755 index 0000000000..f698aa132e --- /dev/null +++ b/collects/meta/build/unix-installer/test-expand-path-var @@ -0,0 +1,47 @@ +#!/bin/sh + +awk -- ' + /^expand_path_var()/ { showing = 1; } + { if (showing) print; } + /^}/ { showing = 0; } +' "`dirname \"$0\"/`/installer-header" > "/tmp/test-$$" +. "/tmp/test-$$" +rm "/tmp/test-$$" + +test() { + foo="$1" + expand_path_var foo + if [ ! "x$foo" = "x$2" ]; then + echo "fail: $1 -> $foo; expected $2" 1>&2 + exit 1 + fi +} + +test 'blah' "blah" +test 'blah blah' "blah blah" +test 'blah blah' "blah blah" +test 'blah=blah' "blah=blah" +test 'x=1 y=2 z=3' "x=1 y=2 z=3" +test '$HOME' "$HOME" +test '$HOME/foo' "$HOME/foo" +test '$HOME/ foo' "$HOME/ foo" +test '$HOME / foo' "$HOME / foo" +test '~' "$HOME" +test '~/' "$HOME/" +test '~/x' "$HOME/x" +test '~/x/y' "$HOME/x/y" +test '~/x /y' "$HOME/x /y" +test '~/ x / y ' "$HOME/ x / y " +test '~/ ' "$HOME/ " +test '~ ' "~ " +test '~eli' "$HOME" +test '~eli ' "~eli " +test '~e li' "~e li" +test '~ eli' "~ eli" +test '~eli /x' "~eli /x" +test '~root/x' "/root/x" +test '~bleh' "~bleh" +test '~bleh ' "~bleh " +test '~/x y' "$HOME/x y" +test '~/x;pwd' "$HOME/x;pwd" +echo "All tests passed."