diff -r 333964c621f1 -r cb59d6afeb61 openpkg/lsync
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/openpkg/lsync Tue Jan 06 23:40:39 2009 +0100
@@ -0,0 +1,339 @@
+#!@l_prefix@/lib/openpkg/bash
+##
+## lsync -- Access Layer Synchronization Tool
+## Copyright (c) 2000-2007 OpenPKG Foundation e.V.
+## Copyright (c) 2000-2007 Ralf S. Engelschall
+##
+## Permission to use, copy, modify, and distribute this software for
+## any purpose with or without fee is hereby granted, provided that
+## the above copyright notice and this permission notice appear in all
+## copies.
+##
+## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+## SUCH DAMAGE.
+##
+
+##
+## filesystem hierarchy configuration
+##
+
+# program name and version/date
+progname="lsync"
+progvers="1.0.4"
+progdate="04-Aug-2001"
+
+# root directory
+# (if empty, .lsyncrc files provide default)
+root=""
+
+# subdirectory where packages are physically installed
+pkgdir="PKG"
+
+# subdirectories which are synchronized between physically
+# installed package areas and access layer
+subdirs="bin,sbin,man,info,include,lib"
+
+##
+## command line option parsing
+##
+
+# default run-time modes
+nop=0
+quiet=0
+trace=0
+help=''
+init=0
+uninstall=0
+local=0
+
+# be aware of .lsyncrc files
+cwd=`pwd`
+while [ 1 ]; do
+ if [ -f "$cwd/.lsyncrc" ]; then
+ set -- `cat $cwd/.lsyncrc` "$@"
+ fi
+ [ ".$cwd" = ./ ] && break
+ cwd=`echo $cwd | sed -e 's;/[^/]*$;;' -e 's;^$;/;'`
+done
+if [ ".$HOME" != . -a -f "$HOME/.lsyncrc" ]; then
+ set -- `cat $HOME/.lsyncrc` "$@"
+fi
+
+# iterate over argument line
+for opt
+do
+ case $opt in
+ -*=*) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;;
+ *) arg='' ;;
+ esac
+ case $opt in
+ -n|--nop ) nop=1 ;;
+ -q|--quiet ) quiet=1 ;;
+ -t|--trace ) trace=1 ;;
+ -v|--version ) version=1 ;;
+ -h|--help ) help="Usage" ;;
+ -i|--init ) init=1 ;;
+ -u|--uninstall ) uninstall=1 ;;
+ -l|--local ) local=1 ;;
+ --root=* ) root=$arg ;;
+ --pkgdir=* ) pkgdir=$arg ;;
+ --subdirs=* ) subdirs=$arg ;;
+ * ) help="Invalid option \`$opt'"; break ;;
+ esac
+done
+
+# error or usage message
+if [ ".$help" != . ]; then
+ if [ ".$help" != ".Usage" ]; then
+ echo "$progname:ERROR: $help" 1>&2
+ fi
+ cat 1>&2 <&2
+ echo "$progname:HINT: use --root=DIR option explicitly on command line" 1>&2
+ echo "$progname:HINT: or implicitly inside an .lsyncrc file in your home" 1>&2
+ echo "$progname:HINT: directory or in any parent directory." 1>&2
+ exit 3
+fi
+
+##
+## helper functions
+##
+
+display_hd () {
+ if [ ".$headline" != . ]; then
+ if [ ".$quiet" = .0 ]; then
+ echo "$headline"
+ fi
+ headline=''
+ fi
+}
+
+display_op () {
+ if [ ".$quiet" = .0 ]; then
+ echo " $@"
+ fi
+}
+
+display_warning () {
+ echo "$progname:WARNING: $*" 1>&2
+}
+
+display_error () {
+ echo "$progname:ERROR: $*" 1>&2
+}
+
+perform_op () {
+ if [ ".$trace" = .1 ]; then
+ echo " \$ $@"
+ fi
+ if [ ".$nop" = .0 ]; then
+ eval "$@"
+ fi
+}
+
+##
+## main processing
+##
+
+# extend a "man" subdir to a complete list with subdirs
+# in order to avoid special cases in the loop processing
+manex=''
+if [ ".$init" = .1 ]; then
+ manex='man'
+fi
+for i in 1 2 3 4 5 6 7 8; do
+ manex="$manex,man/man$i"
+done
+manex=`echo $manex | sed -e 's;^,;;'`
+subdirs=`echo $subdirs | sed -e "s;man;$manex;"`
+
+# special processing: create initial hierarchy
+if [ ".$init" = .1 ]; then
+ if [ ! -d $root ]; then
+ echo "creating $root"
+ perform_op "mkdir $root" || exit 1
+ fi
+ for subdir in $pkgdir `IFS=,; echo $subdirs`; do
+ if [ ! -d "$root/$subdir" ]; then
+ echo "creating $root/$subdir"
+ perform_op "mkdir $root/$subdir" || exit 1
+ fi
+ done
+ exit 0
+fi
+
+# make sure the root directory actually exists
+if [ ! -d "$root" ]; then
+ display_warning "root directory \`$root' does not exist"
+ exit 3
+fi
+
+# if processing is restricted to a local package area, pre-determine its name
+if [ ".$local" = .1 ]; then
+ realroot=`cd $root; pwd`
+ realthis=`pwd`
+ pkgname=`expr "$realthis" : "^$realroot/$pkgdir/\\([^/]*\\).*"`
+ if [ ".$pkgname" = . ]; then
+ display_error "you are not staying under a local package sub-directory"
+ exit 3
+ fi
+fi
+
+# now perform the synchronization for each sub-directory...
+for subdir in `IFS=,; echo $subdirs`; do
+ headline="$root/$subdir:"
+
+ # make sure the subdir actually exists in the access layer
+ if [ ! -d "$root/$subdir" ]; then
+ display_warning "access layer directory \`$root/$subdir' does not exist"
+ continue
+ fi
+
+ #
+ # PASS 1: remove dangling symbolic links in access layer
+ #
+
+ # iterate over all symlinks in the access layer subdir
+ for link in . `ls "$root/$subdir/" | sed -e "s;^$root/$subdir/*;;g"`; do
+ test ".$link" = ".." && continue
+
+ # determine the target file of the symlink
+ target=`ls -l "$root/$subdir/$link" 2>/dev/null | sed -e 's;.*-> *;;'`
+ if [ ".$target" = . ]; then
+ display_warning "$root/$subdir/$link seems to be not a symbolic link"
+ continue
+ fi
+
+ # (optionally) make sure that link target points into local package area
+ if [ ".$local" = .1 -a .`expr $target : "../$pkgdir/$pkgname/.*"` = .0 ]; then
+ continue
+ fi
+
+ # check whether link is valid, i.e., points to
+ # an existing target file or directory
+ if [ ".$uninstall" = .1 ] ||\
+ [ ! -f "$root/$subdir/$target" -a \
+ ! -d "$root/$subdir/$target" ]; then
+ # target no longer exists, so remove dangling symlink
+ display_hd
+ display_op "remove: $link -> $target"
+ perform_op "rm -f $root/$subdir/$link"
+ fi
+ done
+
+ # if we are uninstalling only, our work is now done
+ if [ ".$uninstall" = ".1" ]; then
+ continue
+ fi
+
+ #
+ # PASS 2: create new symbolic links in access layer
+ #
+
+ # calculate the corresponding reverse directory for the current subdir
+ revdir=`echo $subdir | sed -e 's;[^/][^/]*;..;g'`
+
+ # iterate over all package directories
+ for dir in . `ls "$root/$pkgdir/" | sed -e "s;^$root/$pkgdir/*;;g"`; do
+ test ".$dir" = ".." && continue
+
+ # (optionally) make sure that we operate only for the local package area
+ if [ ".$local" = .1 -a ".$dir" != ".$pkgname" ]; then
+ continue
+ fi
+
+ # skip all directories with appended version numbers
+ # in order to support manual versioning of packages
+ case $dir in
+ *-[0-9]* ) continue ;;
+ esac
+
+ # skip if package directory or package sub-directories has sticky bit set
+ if [ ".`ls -l -d $root/$pkgdir/$dir 2>/dev/null | cut -c10`" = .t ] ||\
+ [ ".`ls -l -d $root/$pkgdir/$dir/$subdir 2>/dev/null | cut -c10`" = .t ]; then
+ continue
+ fi
+
+ # check whether the processed subdir exists in package area
+ if [ -d "$root/$pkgdir/$dir/$subdir" ]; then
+
+ # iterate over all files/directories in package's subdir
+ for file in . `ls "$root/$pkgdir/$dir/$subdir/" |\
+ sed -e "s;^$root/$pkgdir/$dir/$subdir/*;;g"`; do
+ test ".$file" = ".." && continue
+
+ # calculate the access layer symlink target
+ target="$revdir/$pkgdir/$dir/$subdir/$file"
+
+ # check whether a possibly conflicting symlink exists
+ exlink=`ls -l $root/$subdir/$file 2>/dev/null`
+ if [ ".$exlink" != . ]; then
+ extarget=`echo $exlink | sed -e 's;.*-> *;;'`
+ if [ ".$extarget" = . ]; then
+ display_warning "$root/$subdir/$file exits, but seems to be not a symbolic link"
+ elif [ ".$extarget" != ".$target" ]; then
+ display_hd
+ display_op "conflict: $file -> $extarget [existing]"
+ display_op " $file -> $target [alternative]"
+ fi
+ continue
+ fi
+
+ # create new symlink in access layer
+ display_hd
+ display_op "create: $file -> $target"
+ perform_op "cd $root/$subdir && ln -s $target $file"
+ done
+ fi
+ done
+done
+