#!/bin/sh # mkswlinks - create links under /usr/local for a software package PATH=/bin:/usr/bin export PATH display_usage() { /bin/cat << 'usage_eof' Usage: mkswlinks [options] Options: -h get help -dest link under instead of /usr/local -src package is in rather than /sw -n don't really install, just print actions -y pre-answer all questions "yes" -q quiet mode (don't print READMEs, etc.) Examples: mkswlinks mh-6.8.3 mkswlinks -n tk-4.0 mkswlinks -y -dest /usr/testing elm-2.4 usage_eof } display_help() { display_usage /bin/cat << 'help_eof' There must be a directory /sw/. For any well-known subdirectory names under (such as bin, sbin, lib, etc.), that subdirectory's _contents_ will be symlinked to the corresponding subdirectory under /usr/local. (For instance, /sw/mh-6.8.3/bin/inc would be symlinked to /usr/local/bin/inc.) Note that typically the contents of a packages lib directory should be another subdirectory, so that for instance /sw/mh-6.8.3/lib/mh-6.8.3 will be symlinked to /usr/local/lib/mh-6.8.3 . (man and catman directories are treated specially, to Do The Right Thing(TM).) Subdirectories under /usr/local are created as needed. Non-well-known subdirectories are an error, and probably mean that this script needs to be updated. If a file "link.sh" exists, it will be executed instead to create the links. If a file "install.sh" exists, the user will be given the option to execute it _in addition to_ making the symlinks. This would typically be used to copy some of the files to local disk, e.g. so there can be a copy of tcsh in /bin . help_eof } error() { echo $* 1>&2 } die() { error $* exit 1 } process_args() { original_args="$@" # to pass to children (UNUSED) really='' # 'echo' if just testing help=0 # 1 -> just display (long) help yes=0 # 1 -> noninteractive (go ahead) quiet=0 # 1 -> don't cat files package='' # name of package (directory) destdir='/usr/local' # where to install the links srcbase='/sw' # where the package directory is arg=$1 if [ $# != "0" ] ; then while ( [ -n "$arg" ] ) do case "$arg" in -h*) help=1; ;; -dest*) destdir=$2; shift; ;; -src*) srcbase=$2; shift; ;; -n*) really=echo; ;; -y*) yes=1; ;; -q*) quiet=1; ;; /*) srcbase=`dirname $arg`; package=`basename $arg`; ;; *) package=$arg; ;; esac shift arg=$1 done fi if [ $help = 1 ] then display_help exit 0 fi if [ -z "$package" ] then echo $package display_usage exit 1 fi srcdir=$srcbase/$package } show_file() { # DEPENDENCIES: quiet, package if [ "$quiet" = "0" ] then echo " " echo "$1 for ${package}:" sed "s/^/ /" $1 echo " " fi } maybe_create_directory() { # DEPENDENCIES: really if [ ! -d $1 ] then $really mkdir -p $1 || die "Unable to create directory \"$1\"." fi } delete_if_symlink() { # NOT YET USED # DEPENDENCIES: really if test -L $1 # builtin works in bash, not in sh then $really rm $1 fi } link_normal_directory() { lnd_dirname=$1 # DEPENDENCIES: srcdir, destdir, really maybe_create_directory $destdir/$lnd_dirname for lnd_subfile in $srcdir/$lnd_dirname/* do lnd_name=`basename $lnd_subfile` lnd_destpath=$destdir/$lnd_dirname/$lnd_name delete_if_symlink $lnd_destpath $really ln -fs $lnd_subfile $lnd_destpath done } link_doc_directory() { # NOTE: $1 is ignored (it should always be "doc") # DEPENDENCIES: srcdir, destdir, really, package maybe_create_directory $destdir/doc delete_if_symlink $destdir/doc/$package $really ln -fs $srcdir/doc $destdir/doc/$package } link_man_directory() { # DEPENDENCIES: srcdir, destdir, really for lnd_subdir in $1/* do link_normal_directory $lnd_subdir done } link_app_defaults_directory() { maybe_create_directory $destdir/lib/X11/app-defaults for lnd_subfile in $srcdir/$1/* do $really ln -fs $lnd_subfile $destdir/lib/X11/app-defaults done } link_info_directory() { error "CAN'T DO INFO DIRECTORIES YET!" } ###################################################################### process_args $1 $2 $3 $4 $5 $6 $7 $8 $9 ###################################################################### if [ ! -d $srcdir ] then error "No package called $package in /sw - can't install." exit 1 fi cd $srcdir # display the package README if there is one: [ "$quiet" != "1" -a -r README ] && show_file README # see if they still want to make links if [ "$yes" != "1" ] then echo "Install links for this package? (y|n)" read yn else yn=y fi case "$yn" in n*) exit 0; ;; *) ;; esac # see if there's a special link.sh file to do instead of default actions: if [ -r link.sh ] then [ "$quiet" != "1" -a -r link.README ] && show_file link.README if [ "$yes" != "1" ] then echo "Execute this link.sh file? (y|n)" read yn else yn=y fi case "$yn" in y*) $really sh link.sh; exit 0; ;; *) echo "No links made."; exit 0; ;; esac fi # default behaviour: process each of the directories in the package: for file in * do case "$file" in README|link.*|install.*|BUILD*) ;; man|catman) link_man_directory $file ;; bin|sbin|lib|libexec|include|etc) link_normal_directory $file ;; doc) link_doc_directory $file ;; app-defaults) link_app_defaults_directory $file ;; info) error "######################################"; error "# Can't handle info directories yet! #"; error "######################################"; ;; root) echo "This package contains files that must be "; echo "installed to local disk. To do so, you "; echo "must let this program run the package's "; echo "install.sh script." ;; *) error "I don't know what to do with \"$file\"!" ;; esac done # see if there's a special install.sh script to run at the end: if [ -r install.sh ] then [ "$quiet" != "1" -a -r install.README ] && show_file install.README if [ "$yes" != "1" ] then echo "Execute this install.sh file? (y|n)" read yn else yn=y fi case "$yn" in y*) $really sh install.sh; ;; *) echo "OK, install.sh not run."; ;; esac fi exit 0