]> ruderich.org/simon Gitweb - config/dotfiles.git/blobdiff - lib.sh
lib.sh: Add installed_path(), a portable `which`.
[config/dotfiles.git] / lib.sh
diff --git a/lib.sh b/lib.sh
index 49ce998660f3132b0b33d2bbca86e5ac936719f6..70aefbe48592edd5249b3a0182e135f67e3c2721 100644 (file)
--- a/lib.sh
+++ b/lib.sh
@@ -2,21 +2,61 @@
 #
 # Their setup.sh script sources this file.
 
+# Copyright (C) 2009-2013  Simon Ruderich
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
 
 # csh gives the error "Unknown colorls variable `su'." when used with newer
 # options supported by Zsh or GNU ls.
 unset LS_COLORS
 
 
-# Check if the given program is installed. Returns 0 if it exists, 1
-# otherwise; so it can be used in if.
+# Check if the given program is installed. `type` is portable, `which` is not.
 installed() {
-    which $1 2>&1 | perl -ne 'if (not m{^/}) { exit 1 }'
+    type "$1" >/dev/null 2>&1
+}
+# Get the path of the given program. Thanks to Gilles on [1] (read on
+# 2013-03-10) for the PATH-walking idea. `which` is not portable and `type`
+# has no well-formed output format.
+#
+# [1]: http://unix.stackexchange.com/questions/4988/how-do-i-test-to-see-if-an-application-exists-in-path/4991
+installed_path() {
+    test -z "$1" && return 1
+
+    # Keep IFS change local.
+    (
+        IFS=:
+        # Walk PATH.
+        for directory in $PATH; do
+            if test -x "$directory/$1"; then
+                echo "$directory/$1"
+                return 0
+            fi
+        done
+
+        return 1
+    )
 }
 
-# Prints the current OS. Supported are Debian (debian), Gentoo (gentoo) and
-# Mac OS X (darwin) at the moment. If an unsupported OS is used an error is
-# printed.
+# Print the current OS. The following OS are supported at the moment:
+# - Debian (debian)
+# - Gentoo (gentoo)
+# - Mac OS X (darwin)
+# - Solaris/OpenSolaris (sun)
+# - FreeBSD (freebsd)
+# If an unsupported OS is used an error is printed.
 os() {
     if [ -f /etc/debian_version ]; then
         echo debian
@@ -24,6 +64,10 @@ os() {
         echo gentoo
     elif [ x`uname` = xDarwin ]; then
         echo darwin
+    elif [ x`uname` = xSunOS ]; then
+        echo sun
+    elif [ x`uname` = xFreeBSD ]; then
+        echo freebsd
     else
         echo unsupported OS! >&2
         return 1
@@ -38,7 +82,8 @@ os() {
 link() {
     # Get all necessary paths.
     pwd=`pwd`
-    base=`dirname "$2"`
+    base=`echo "$2" | sed "s|\~|$HOME|"` # expand ~, some sh don't do it
+    base=`dirname "$base"`
     source=`echo "$pwd/$1" | sed "s|$base/||"`
     target=`basename "$2"`
 
@@ -47,13 +92,14 @@ link() {
 
     # Abort if the target file exists and is no symbolic link. Prevents
     # overwriting real files.
-    if [ -e "$target" -a ! -h "$target" ]; then
+    if [ \( -f "$target" -a ! -h "$target" \) -o \
+         \( -s "$target" -a ! -h "$target" \) ]; then
         echo "link(): target '$target' exists already and is no symbolic link!" >&2
         exit 1
     fi
 
-    # Make sure the source exists.
-    if [ ! -e "$source" ]; then
+    # Make sure the source exists (is file, directory or link).
+    if [ ! -f "$source" -a ! -d "$source" -a ! -h "$source" ]; then
         echo "link(): source '$source' doesn't exist!" >&2
         exit 1
     fi