> Norman Ramsey <[EMAIL PROTECTED]> writes:
 > > I can always call my script 'darcs', have it do what it understands
 > > and then delegate the rest to the next darcs on my $PATH.
 > 
 > Currently all my wrappers are called "twb-foo" because I couldn't work
 > out a way to elegantly remove entries from $PATH in POSIX sh.  In
 > particular, I couldn't handle the case where the wrapper was not from
 > the first dir in $PATH.
 > 
 > I assume you've found a way to do this robustly, since from your
 > sentiment I doubt anything else would be acceptable to you.  

Oh no, I have a double standard---I'm quite willing to write crappy
code for myself, as long as nobody ever sees it.  But you've been
quite polite with all my ranting, and I do believe this code is
robust, although I'm not sure I tested it on anything three deep since
after the day it was written.

 > Would you care to share your code?

Here is a really hideous ksh script called 'nextbinary'.
Your shell script does its thing and then something like

  exec `nextbinary $0` arguments ...

nextbinary returns the next binary on the $PATH that is not the same
file as the one passed in as a parameter.  I had to write samefile.c
to test to see if two files were the same file, since I couldn't find
an easy way to do this from whatever ksh version I was using that
year.

I don't muck with $PATH but rather iterate through its elements
explicitly. 

I'm sure a knowledgeable person could translate the ksh to bash.
The samefile.c program is straightforward and not embarrassing.


Norman

#!/bin/ksh
#
#       nextbinary fullpathname
#
#       searches user's $PATH for next binary after current one

if [ $# -ne 1 ]; then
  echo "Usage: $0 pathname" 1>&2; exit 1;
fi

  full="$1"
  base="`basename $1`"
  dir="`dirname $1`"
  found=
  xxx="$IFS"
  IFS=":"
  case $dir in
    */*)
       for i in $PATH ; do
         IFS="$xxx"
         if   samefile $i/$base $full; then found=1
         elif [ -n "$found" -a -x "$i/$base" -a ! -d "$i/$base" ]; then
           print $i/$base; exit 0
         fi
       done
       IFS="$xxx"
        ;;
    *) 
       for i in $PATH ; do
         IFS="$xxx"
         if   [ -z "$found" -a ! -d "$i/$base" ] && samefile  "$i/$base" $full; 
then
           found=1
         elif [ -n "$found" -a -x "$i/$base" -a ! -d "$i/$base" ]; then
           print $i/$base; exit 0
         fi
       done
       if [ -z "$found" ]; then # didn't find exactly this file on path
         # look for first executable file on path
         IFS=":"
         for i in $PATH ; do
           IFS="$xxx"
           if   [ -z "$found" -a -x "$i/$base" -a ! -d "$i/$base" ]; then 
found=1
           elif [ -n "$found" -a -x "$i/$base" -a ! -d "$i/$base" ]; then
             print $i/$base; exit 0
           fi
         done
         IFS="$xxx"
       fi
       ;;
    esac
  echo "No $base on" '$PATH' after "$full" 1>&2
  exit 1

/* samefile -- succeeds if two files exist and are the same */

#include <sys/types.h>
#include <sys/stat.h>

#include <stdio.h>

int main (int argc, char *argv[]) {
  int i;
  struct stat buf1, buf2;
  if (argc != 3) {
    fprintf(stderr, "Usage: %s file1 file2\n", argv[0]);
    exit(2);
  }
  if (stat(argv[1], &buf1)) exit(1);
  if (stat(argv[2], &buf2)) exit(1);
  if (buf1.st_dev == buf2.st_dev && buf1.st_ino == buf2.st_ino)
    exit(0);
  else
    exit(1);
}

_______________________________________________
darcs-users mailing list
[email protected]
http://lists.osuosl.org/mailman/listinfo/darcs-users

Reply via email to