commit e78d55188900c78b110900d6e0c8ee7ee9ce18b1
parent 4253b833e3c9467a4c8688505313d52ff34ca3d4
Author: Jaromil <jaromil@dyne.org>
Date:   Wed, 10 Apr 2013 12:23:19 +0200
fixes for compilation on osx 10.8 with latest xcode
Diffstat:
3 files changed, 115 insertions(+), 793 deletions(-)
diff --git a/build/build-osx.sh b/build/build-osx.sh
@@ -15,17 +15,23 @@
 builddir=`pwd`
 
 #cc="${builddir}/cc-static.zsh"
-cc="${builddir}/clang-static-osx.sh"
+#cc="gcc-4.7"
+#cpp="cpp-4.7"
+cc="llvm-gcc"
+cpp="llvm-cpp-4.2"
+# ${builddir}/clang-static-osx.sh"
 
 #cflags="-arch x86_64 -arch i386 -O2"
-
-cflags=(-I/opt/local/include -I/usr/include)
-cflags+=(-arch x86_64)
-cflags+=(-arch i386)
+OSX_SDK=10.7
+cflags=(-I/usr/local/include -I/usr/include)
+cflags+=(-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${OSX_SDK}.sdk/usr/include)
+# cflags+=(-arch x86_64)
+# cflags+=(-arch i386)
 cflags+=(-O2)
 
 
-ldflags="-L/opt/local/lib -L/usr/lib"
+ldflags=(-L/usr/local/lib -L/usr/lib)
+ldflags+=(-L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${OSX_SDK}.sdk/usr/lib)
 
 
 target=all
@@ -67,11 +73,64 @@ copydeps() {
 	done # 1st
 
 	cp $1 build/osx/`basename $1`.bin
+	chmod +w build/osx/`basename $1`.bin
+	strip build/osx/`basename $1`.bin
+	for d in `cat $tmp | sort | uniq`; do
+	    if ! [ -r build/osx/dylib/`basename $d` ]; then
+		cp $d build/osx/dylib/
+		print "  `basename $d`"
+	    fi
+	done
+
+		# create a wrapper
+	cat <<EOF > build/osx/`basename $1`
+#!/usr/bin/env zsh
+test -r \$HOME/Mail/jaro/bin/jaro && PDIR=\$HOME/Mail/jaro
+test -r jaro/bin/jaro && PDIR="\`pwd\`/jaro"
+test \$JAROMAIL && PDIR=\$JAROMAIL
+DYLD_LIBRARY_PATH=\$PDIR/bin/dylib:\$DYLD_LIBRARY_PATH \\
+\$PDIR/bin/`basename $1`.bin \${=@}
+EOF
+	chmod +x build/osx/`basename $1`
+
+}
+
+
+copydeps_brew() {
+	# copy a binary and all dependencies until 3rd level
+	print "`basename $1`"
+
+	tmp="/tmp/build_`basename $1`";
+	rm -f $tmp; touch $tmp
+
+	libs=`otool -L $1 | awk '
+		/^\// {next} /\/usr\/local/ {print $1}'`
+
+	for p1 in ${(f)libs}; do
+		echo "$p1" >> $tmp
+		# second pass
+		libs2=`otool -L $p1 | awk '
+			/^\// {next} /\/usr\/local/ {print $1}'`
+
+		for p2 in ${(f)libs2}; do
+			echo "$p2" >> $tmp
+			# third pass
+			libs3=`otool -L $p2 | awk '
+				/^\// {next} /\/usr\/local/ {print $1}'`
+
+			for p3 in ${(f)libs3}; do
+				echo "$p3" >> $tmp
+			done # 3rd
+		done # 2nd
+	done # 1st
+
+	cp $1 build/osx/`basename $1`.bin
+	chmod +w build/osx/`basename $1`.bin
 	strip build/osx/`basename $1`.bin
 	for d in `cat $tmp | sort | uniq`; do
 	    if ! [ -r build/osx/dylib/`basename $d` ]; then
 		cp $d build/osx/dylib/
-		print "`basename $d`"
+		print "  `basename $d`"
 	    fi
 	done
 
@@ -88,6 +147,8 @@ EOF
 
 }
 
+
+
 print "Building Jaro Mail binary stash for Apple/OSX"
 
 if ! [ -r /opt/local/bin/port ]; then
@@ -111,8 +172,8 @@ fi
 # build our own address parser
     pushd src
     print "Address parser"
-    $cc -c fetchaddr.c helpers.c rfc2047.c rfc822.c; \
-	$cc -o fetchaddr fetchaddr.o helpers.o rfc2047.o rfc822.o;
+    $cc ${=cflags} -c fetchaddr.c helpers.c rfc2047.c rfc822.c
+    $cc -o fetchaddr fetchaddr.o helpers.o rfc2047.o rfc822.o ${=ldflags};
     popd
 }
 
@@ -121,9 +182,10 @@ fi
 # build mairix
     pushd src/mairix
     print "Search engine and date parser"
-    CC="$cc" LD=/usr/bin/ld CPP=/usr/bin/cpp \
-	./configure --disable-gzip-mbox --disable-bzip-mbox \
-	> /dev/null ; make 2>&1 > /dev/null
+    CFLAGS="${=cflags} ${=ldflags} -L/usr/local/opt/bison/lib" \
+    CFLAGS="$CFLAGS -L/usr/local/opt/flex/lib -I/usr/local/opt/flex/include" \
+    CC="$cc" LD=ld CPP="$cpp"  \
+	./configure --disable-gzip-mbox --disable-bzip-mbox ; make 
     popd
 }
 
@@ -131,8 +193,8 @@ fi
     test "$target" = "all" } && {
 # build our own fetchdate
     pushd src
-    $cc -I mairix -c fetchdate.c
-    $cc -DHAS_STDINT_H -DHAS_INTTYPES_H \
+    $cc ${=cflags} ${=ldflags} -I mairix -c fetchdate.c
+    $cc ${=cflags} ${=ldflags} -DHAS_STDINT_H -DHAS_INTTYPES_H \
 	-o fetchdate fetchdate.o \
 	mairix/datescan.o mairix/db.o mairix/dotlock.o \
 	mairix/expandstr.o mairix/glob.o mairix/md5.o \
@@ -148,8 +210,8 @@ fi
     test "$target" = "all" } && {
 # build our own dotlock
     pushd src
-    $cc -c dotlock.c
-    $cc -o dotlock dotlock.o
+    $cc ${=cflags} -c dotlock.c
+    $cc ${=ldflags} -o dotlock dotlock.o
     popd
 }
 
@@ -171,20 +233,35 @@ fi
     echo "Compiling Mutt (MUA)"
     pushd src/mutt-1.5.21
 
-    CC=clang CFLAGS="$cflags" CPPFLAGS="-I/opt/local/include" LDFLAGS="$ldflags" ./configure \
+    CC="$gcc" CPP="$cpp" CFLAGS="${=cflags} -I/usr/local/Cellar/gettext/0.18.2/include" \
+    CPPFLAGS="${=cflags}" LDFLAGS="${=ldflags} -L/usr/local/Cellar/gettext/0.18.2/lib" ./configure \
 	--with-ssl --with-gnutls --enable-imap --disable-debug \
 	--with-slang --disable-gpgme \
 	--enable-hcache --with-regex --with-tokyocabinet \
-	--with-mixmaster=${root}/src/mixmaster --enable-pgp \
-	> /dev/null
-    make mutt > /dev/null
-    { test $? = 0 } && {
-	 mv mutt mutt-jaro
-	 mv mutt_dotlock dotlock-mutt
-    }
+	--with-mixmaster=${root}/src/mixmaster --enable-pgp
+    make keymap_defs.h
+    make reldate.h
+    CFLAGS="-I/usr/local/Cellar/gettext/0.18.2/include" make hcversion.h
+    make mutt
+    make pgpewrap
+    { test $? = 0 } && { mv mutt mutt-jaro }
     popd
 }
 
+# build our own lynx (no ssl)
+{ test "$target" = "lynx" } || {
+  test "$target" = "all" } && {
+  echo "Compiling Lynx (html 2 txt)"
+  pushd src/lynx2-8-7
+    CC="$gcc" CPP="$cpp" CFLAGS="${=cflags} -I/usr/local/Cellar/gettext/0.18.2/include" \
+    CPPFLAGS="${=cflags}" LDFLAGS="${=ldflags} -L/usr/local/Cellar/gettext/0.18.2/lib" ./configure \
+    --disable-trace --enable-nls --with-screen=slang --enable-widec --enable-default-colors \
+    --disable-file-upload --disable-persistent-cookie --with-bzlib --with-zlib \
+    --disable-finger --disable-gopher --disable-news --disable-ftp --disable-dired \
+    --enable-cjk --enable-japanese-utf8 --enable-charset-selection
+  make
+  popd
+}
 
  #  CFLAGS="${=cflags}" \
 
@@ -201,17 +278,20 @@ fi
 # cp src/msmtp/src/msmtp build/osx/
     cp -v src/dotlock build/osx/
     copydeps ${root}/src/mutt-1.5.21/mutt-jaro
-    copydeps ${root}/src/mutt-1.5.21/dotlock-mutt
     copydeps ${root}/src/mutt-1.5.21/pgpewrap
-    copydeps /opt/local/bin/gfind
-    copydeps /opt/local/bin/msmtp
-    copydeps /opt/local/bin/gpg
+    copydeps_brew /usr/local/bin/gfind
+    copydeps_brew /usr/local/bin/msmtp
+    copydeps_brew /usr/local/bin/gpg
     mv build/osx/gpg build/osx/gpg-jaro
-    copydeps /opt/local/bin/pinentry
-    copydeps /opt/local/bin/abook
-    copydeps /opt/local/bin/lynx
+    copydeps_brew /usr/local/bin/pinentry
+    copydeps_brew /usr/local/bin/abook
+    copydeps ${root}/src/lynx2-8-7/lynx
+    cp ${root}/src/lynx2-8-7/lynx.cfg build/osx/lynx.cfg
+
     copydeps /opt/local/bin/fetchmail
-    copydeps /opt/local/bin/procmail
+
+    # system wide
+    rm build/osx/dylib/libiconv.2.dylib
 }
 
 
diff --git a/build/clang-static-osx.sh b/build/clang-static-osx.sh
@@ -24,14 +24,14 @@
 
 # configuration variables
 
-cc=clang
-libdir="/opt/local/lib"
+cc=gcc
+libdir="/usr/local/lib"
 
 typeset -a arguments
 typeset -a cflags
 
 cflags+=(-arch x86_64)
-cflags+=(-arch i386)
+# cflags+=(-arch i386)
 
 ##########################
 
diff --git a/src/mutt-1.5.21/mutt_dotlock.c b/src/mutt-1.5.21/mutt_dotlock.c
@@ -1,758 +0,0 @@
-/*
- * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
- * Copyright (C) 1998-2001,2007 Thomas Roessler <roessler@does-not-exist.org>
- * 
- *     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 2 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, write to the Free Software
- *     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */ 
-
-/*
- * This module either be compiled into Mutt, or it can be
- * built as a separate program. For building it
- * separately, define the DL_STANDALONE preprocessor
- * macro.
- */
-
-#if HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <unistd.h>
-#include <dirent.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <errno.h>
-#include <time.h>
-#include <fcntl.h>
-#include <limits.h>
-
-#ifndef _POSIX_PATH_MAX
-#include <limits.h>
-#endif
-
-#include "dotlock.h"
-
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-
-#ifdef DL_STANDALONE
-# include "reldate.h"
-#endif
-
-#define MAXLINKS 1024 /* maximum link depth */
-
-#ifdef DL_STANDALONE
-
-# define LONG_STRING 1024
-# define MAXLOCKATTEMPT 5
-
-# define strfcpy(A,B,C) strncpy (A,B,C), *(A+(C)-1)=0
-
-# ifdef USE_SETGID
-
-#  ifdef HAVE_SETEGID
-#   define SETEGID setegid
-#  else
-#   define SETEGID setgid
-#  endif
-#  ifndef S_ISLNK
-#   define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK ? 1 : 0)
-#  endif
-
-# endif
-
-# ifndef HAVE_SNPRINTF
-extern int snprintf (char *, size_t, const char *, ...);
-# endif
-
-#else  /* DL_STANDALONE */
-
-# ifdef USE_SETGID
-#   error Do not try to compile dotlock as a mutt module when requiring egid switching!
-# endif
-
-# include "mutt.h"
-# include "mx.h"
-
-#endif /* DL_STANDALONE */
-
-static int DotlockFlags;
-static int Retry = MAXLOCKATTEMPT;
-
-#ifdef DL_STANDALONE
-static char *Hostname;
-#endif
-
-#ifdef USE_SETGID
-static gid_t UserGid;
-static gid_t MailGid;
-#endif
-
-static int dotlock_deference_symlink (char *, size_t, const char *);
-static int dotlock_prepare (char *, size_t, const char *, int fd);
-static int dotlock_check_stats (struct stat *, struct stat *);
-static int dotlock_dispatch (const char *, int fd);
-
-#ifdef DL_STANDALONE
-static int dotlock_init_privs (void);
-static void usage (const char *);
-#endif
-
-static void dotlock_expand_link (char *, const char *, const char *);
-static void BEGIN_PRIVILEGED (void);
-static void END_PRIVILEGED (void);
-
-/* These functions work on the current directory.
- * Invoke dotlock_prepare () before and check their
- * return value.
- */
-
-static int dotlock_try (void);
-static int dotlock_unlock (const char *);
-static int dotlock_unlink (const char *);
-static int dotlock_lock (const char *);
-
-
-#ifdef DL_STANDALONE
-
-#define check_flags(a) if (a & DL_FL_ACTIONS) usage (argv[0])
-
-int main (int argc, char **argv)
-{
-  int i;
-  char *p;
-  struct utsname utsname;
-
-  /* first, drop privileges */
-  
-  if (dotlock_init_privs () == -1)
-    return DL_EX_ERROR;
-
-
-  /* determine the system's host name */
-  
-  uname (&utsname);
-  if (!(Hostname = strdup (utsname.nodename)))	/* __MEM_CHECKED__ */
-    return DL_EX_ERROR;
-  if ((p = strchr (Hostname, '.')))
-    *p = '\0';
-
-
-  /* parse the command line options. */
-  DotlockFlags = 0;
-  
-  while ((i = getopt (argc, argv, "dtfupr:")) != EOF)
-  {
-    switch (i)
-    {
-      /* actions, mutually exclusive */
-      case 't': check_flags (DotlockFlags); DotlockFlags |= DL_FL_TRY; break;
-      case 'd': check_flags (DotlockFlags); DotlockFlags |= DL_FL_UNLINK; break;
-      case 'u': check_flags (DotlockFlags); DotlockFlags |= DL_FL_UNLOCK; break;
-
-      /* other flags */
-      case 'f': DotlockFlags |= DL_FL_FORCE; break;
-      case 'p': DotlockFlags |= DL_FL_USEPRIV; break;
-      case 'r': DotlockFlags |= DL_FL_RETRY; Retry = atoi (optarg); break;
-      
-      default: usage (argv[0]);
-    }
-  }
-
-  if (optind == argc || Retry < 0)
-    usage (argv[0]);
-
-  return dotlock_dispatch (argv[optind], -1);
-}
-
-
-/* 
- * Determine our effective group ID, and drop 
- * privileges.
- * 
- * Return value:
- * 
- *  0 - everything went fine
- * -1 - we couldn't drop privileges.
- * 
- */
-
-
-static int
-dotlock_init_privs (void)
-{
-
-# ifdef USE_SETGID
-  
-  UserGid = getgid ();
-  MailGid = getegid ();
-
-  if (SETEGID (UserGid) != 0)
-    return -1;
-
-# endif
-
-  return 0;
-}
-  
-
-#else  /* DL_STANDALONE */
-
-/* 
- * This function is intended to be invoked from within
- * mutt instead of mx.c's invoke_dotlock ().
- */
-
-int dotlock_invoke (const char *path, int fd, int flags, int retry)
-{
-  int currdir;
-  int r;
-
-  DotlockFlags = flags;
-  
-  if ((currdir = open (".", O_RDONLY)) == -1)
-    return DL_EX_ERROR;
-
-  if (!(DotlockFlags & DL_FL_RETRY) || retry)
-    Retry = MAXLOCKATTEMPT;
-  else
-    Retry = 0;
-  
-  r = dotlock_dispatch (path, fd);
-  
-  fchdir (currdir);
-  close (currdir);
-  
-  return r;
-}
-
-#endif  /* DL_STANDALONE */
-
-
-static int dotlock_dispatch (const char *f, int fd)
-{
-  char realpath[_POSIX_PATH_MAX];
-
-  /* If dotlock_prepare () succeeds [return value == 0],
-   * realpath contains the basename of f, and we have
-   * successfully changed our working directory to
-   * `dirname $f`.  Additionally, f has been opened for
-   * reading to verify that the user has at least read
-   * permissions on that file.
-   * 
-   * For a more detailed explanation of all this, see the
-   * lengthy comment below.
-   */
-
-  if (dotlock_prepare (realpath, sizeof (realpath), f, fd) != 0)
-    return DL_EX_ERROR;
-
-  /* Actually perform the locking operation. */
-
-  if (DotlockFlags & DL_FL_TRY)
-    return dotlock_try ();
-  else if (DotlockFlags & DL_FL_UNLOCK)
-    return dotlock_unlock (realpath);
-  else if (DotlockFlags & DL_FL_UNLINK)
-    return dotlock_unlink (realpath);
-  else /* lock */
-    return dotlock_lock (realpath);
-}
-
-  
-/*
- * Get privileges 
- * 
- * This function re-acquires the privileges we may have
- * if the user told us to do so by giving the "-p"
- * command line option.
- * 
- * BEGIN_PRIVILEGES () won't return if an error occurs.
- * 
- */
-
-static void
-BEGIN_PRIVILEGED (void)
-{
-#ifdef USE_SETGID
-  if (DotlockFlags & DL_FL_USEPRIV)
-  {
-    if (SETEGID (MailGid) != 0)
-    {
-      /* perror ("setegid"); */
-      exit (DL_EX_ERROR);
-    }
-  }
-#endif
-}
-
-/*
- * Drop privileges
- * 
- * This function drops the group privileges we may have.
- * 
- * END_PRIVILEGED () won't return if an error occurs.
- *
- */
-
-static void
-END_PRIVILEGED (void)
-{
-#ifdef USE_SETGID
-  if (DotlockFlags & DL_FL_USEPRIV)
-  {
-    if (SETEGID (UserGid) != 0)
-    {
-      /* perror ("setegid"); */
-      exit (DL_EX_ERROR);
-    }
-  }
-#endif
-}
-
-#ifdef DL_STANDALONE
-
-/*
- * Usage information.
- * 
- * This function doesn't return.
- * 
- */
-
-static void 
-usage (const char *av0)
-{
-  fprintf (stderr, "dotlock [Mutt %s (%s)]\n", VERSION, ReleaseDate);
-  fprintf (stderr, "usage: %s [-t|-f|-u|-d] [-p] [-r <retries>] file\n",
-	  av0);
-
-  fputs ("\noptions:"
-	"\n  -t\t\ttry"
-	"\n  -f\t\tforce"
-	"\n  -u\t\tunlock"
-	"\n  -d\t\tunlink"
-	"\n  -p\t\tprivileged"
-#ifndef USE_SETGID
-	" (ignored)"
-#endif
-	"\n  -r <retries>\tRetry locking"
-	"\n", stderr);
-  
-  exit (DL_EX_ERROR);
-}
-
-#endif
-
-/*
- * Access checking: Let's avoid to lock other users' mail
- * spool files if we aren't permitted to read them.
- * 
- * Some simple-minded access (2) checking isn't sufficient
- * here: The problem is that the user may give us a
- * deeply nested path to a file which has the same name
- * as the file he wants to lock, but different
- * permissions, say, e.g.
- * /tmp/lots/of/subdirs/var/spool/mail/root.
- * 
- * He may then try to replace /tmp/lots/of/subdirs by a
- * symbolic link to / after we have invoked access () to
- * check the file's permissions.  The lockfile we'd
- * create or remove would then actually be
- * /var/spool/mail/root.
- * 
- * To avoid this attack, we proceed as follows:
- * 
- * - First, follow symbolic links a la
- *   dotlock_deference_symlink ().
- * 
- * - get the result's dirname.
- * 
- * - chdir to this directory.  If you can't, bail out.
- * 
- * - try to open the file in question, only using its
- *   basename.  If you can't, bail out.
- * 
- * - fstat that file and compare the result to a
- *   subsequent lstat (only using the basename).  If
- *   the comparison fails, bail out.
- * 
- * dotlock_prepare () is invoked from main () directly
- * after the command line parsing has been done.
- *
- * Return values:
- * 
- * 0 - Evereything's fine.  The program's new current
- *     directory is the contains the file to be locked.
- *     The string pointed to by bn contains the name of
- *     the file to be locked.
- * 
- * -1 - Something failed. Don't continue.
- * 
- * tlr, Jul 15 1998
- */
-
-static int
-dotlock_check_stats (struct stat *fsb, struct stat *lsb)
-{
-  /* S_ISLNK (fsb->st_mode) should actually be impossible,
-   * but we may have mixed up the parameters somewhere.
-   * play safe.
-   */
-
-  if (S_ISLNK (lsb->st_mode) || S_ISLNK (fsb->st_mode))
-    return -1;
-  
-  if ((lsb->st_dev != fsb->st_dev) ||
-     (lsb->st_ino != fsb->st_ino) ||
-     (lsb->st_mode != fsb->st_mode) ||
-     (lsb->st_nlink != fsb->st_nlink) ||
-     (lsb->st_uid != fsb->st_uid) ||
-     (lsb->st_gid != fsb->st_gid) ||
-     (lsb->st_rdev != fsb->st_rdev) ||
-     (lsb->st_size != fsb->st_size))
-  {
-    /* something's fishy */
-    return -1;
-  }
-  
-  return 0;
-}
-
-static int
-dotlock_prepare (char *bn, size_t l, const char *f, int _fd)
-{
-  struct stat fsb, lsb;
-  char realpath[_POSIX_PATH_MAX];
-  char *basename, *dirname;
-  char *p;
-  int fd;
-  int r;
-  
-  if (dotlock_deference_symlink (realpath, sizeof (realpath), f) == -1)
-    return -1;
-  
-  if ((p = strrchr (realpath, '/')))
-  {
-    *p = '\0';
-    basename = p + 1;
-    dirname = realpath;
-  }
-  else
-  {
-    basename = realpath;
-    dirname = ".";
-  }
-
-  if (strlen (basename) + 1 > l)
-    return -1;
-  
-  strfcpy (bn, basename, l);
-  
-  if (chdir (dirname) == -1)
-    return -1;
-
-  if (_fd != -1)
-    fd = _fd;
-  else if ((fd = open (basename, O_RDONLY)) == -1)
-    return -1;
-  
-  r = fstat (fd, &fsb);
-  
-  if (_fd == -1)
-    close (fd);
-  
-  if (r == -1)
-    return -1;
-  
-  if (lstat (basename, &lsb) == -1)
-    return -1;
-
-  if (dotlock_check_stats (&fsb, &lsb) == -1)
-    return -1;
-
-  return 0;
-}
-
-/*
- * Expand a symbolic link.
- * 
- * This function expects newpath to have space for
- * at least _POSIX_PATH_MAX characters.
- *
- */
-
-static void 
-dotlock_expand_link (char *newpath, const char *path, const char *link)
-{
-  const char *lb = NULL;
-  size_t len;
-
-  /* link is full path */
-  if (*link == '/')
-  {
-    strfcpy (newpath, link, _POSIX_PATH_MAX);
-    return;
-  }
-
-  if ((lb = strrchr (path, '/')) == NULL)
-  {
-    /* no path in link */
-    strfcpy (newpath, link, _POSIX_PATH_MAX);
-    return;
-  }
-
-  len = lb - path + 1;
-  memcpy (newpath, path, len);
-  strfcpy (newpath + len, link, _POSIX_PATH_MAX - len);
-}
-
-
-/*
- * Deference a chain of symbolic links
- * 
- * The final path is written to d.
- *
- */
-
-static int
-dotlock_deference_symlink (char *d, size_t l, const char *path)
-{
-  struct stat sb;
-  char realpath[_POSIX_PATH_MAX];
-  const char *pathptr = path;
-  int count = 0;
-  
-  while (count++ < MAXLINKS)
-  {
-    if (lstat (pathptr, &sb) == -1)
-    {
-      /* perror (pathptr); */
-      return -1;
-    }
-    
-    if (S_ISLNK (sb.st_mode))
-    {
-      char linkfile[_POSIX_PATH_MAX];
-      char linkpath[_POSIX_PATH_MAX];
-      int len;
-
-      if ((len = readlink (pathptr, linkfile, sizeof (linkfile) - 1)) == -1)
-      {
-	/* perror (pathptr); */
-	return -1;
-      }
-      
-      linkfile[len] = '\0';
-      dotlock_expand_link (linkpath, pathptr, linkfile);
-      strfcpy (realpath, linkpath, sizeof (realpath));
-      pathptr = realpath;
-    }
-    else
-      break;
-  }
-
-  strfcpy (d, pathptr, l);
-  return 0;
-}
-
-/*
- * Dotlock a file.
- * 
- * realpath is assumed _not_ to be an absolute path to
- * the file we are about to lock.  Invoke
- * dotlock_prepare () before using this function!
- * 
- */
-
-#define HARDMAXATTEMPTS 10
-
-static int
-dotlock_lock (const char *realpath)
-{
-  char lockfile[_POSIX_PATH_MAX + LONG_STRING];
-  char nfslockfile[_POSIX_PATH_MAX + LONG_STRING];
-  size_t prev_size = 0;
-  int fd;
-  int count = 0;
-  int hard_count = 0;
-  struct stat sb;
-  time_t t;
-  
-  snprintf (nfslockfile, sizeof (nfslockfile), "%s.%s.%d",
-	   realpath, Hostname, (int) getpid ());
-  snprintf (lockfile, sizeof (lockfile), "%s.lock", realpath);
-
-  
-  BEGIN_PRIVILEGED ();
-
-  unlink (nfslockfile);
-
-  while ((fd = open (nfslockfile, O_WRONLY | O_EXCL | O_CREAT, 0)) < 0)
-  {
-    END_PRIVILEGED ();
-
-  
-    if (errno != EAGAIN)
-    {
-      /* perror ("cannot open NFS lock file"); */
-      return DL_EX_ERROR;
-    }
-
-    
-    BEGIN_PRIVILEGED ();
-  }
-
-  END_PRIVILEGED ();
-
-  
-  close (fd);
-  
-  while (hard_count++ < HARDMAXATTEMPTS)
-  {
-
-    BEGIN_PRIVILEGED ();
-    link (nfslockfile, lockfile);
-    END_PRIVILEGED ();
-
-    if (stat (nfslockfile, &sb) != 0)
-    {
-      /* perror ("stat"); */
-      return DL_EX_ERROR;
-    }
-
-    if (sb.st_nlink == 2)
-      break;
-
-    if (count == 0)
-      prev_size = sb.st_size;
-
-    if (prev_size == sb.st_size && ++count > Retry)
-    {
-      if (DotlockFlags & DL_FL_FORCE)
-      {
-	BEGIN_PRIVILEGED ();
-	unlink (lockfile);
-	END_PRIVILEGED ();
-
-	count = 0;
-	continue;
-      }
-      else
-      {
-	BEGIN_PRIVILEGED ();
-	unlink (nfslockfile);
-	END_PRIVILEGED ();
-	return DL_EX_EXIST;
-      }
-    }
-    
-    prev_size = sb.st_size;
-    
-    /* don't trust sleep (3) as it may be interrupted
-     * by users sending signals. 
-     */
-    
-    t = time (NULL);
-    do {
-      sleep (1);
-    } while (time (NULL) == t);
-  }
-
-  BEGIN_PRIVILEGED ();
-  unlink (nfslockfile);
-  END_PRIVILEGED ();
-
-  return DL_EX_OK;
-}
-
-
-/*
- * Unlock a file. 
- * 
- * The same comment as for dotlock_lock () applies here.
- * 
- */
-
-static int
-dotlock_unlock (const char *realpath)
-{
-  char lockfile[_POSIX_PATH_MAX + LONG_STRING];
-  int i;
-
-  snprintf (lockfile, sizeof (lockfile), "%s.lock",
-	   realpath);
-  
-  BEGIN_PRIVILEGED ();
-  i = unlink (lockfile);
-  END_PRIVILEGED ();
-  
-  if (i == -1)
-    return DL_EX_ERROR;
-  
-  return DL_EX_OK;
-}
-
-/* remove an empty file */
-
-static int
-dotlock_unlink (const char *realpath)
-{
-  struct stat lsb;
-  int i = -1;
-
-  if (dotlock_lock (realpath) != DL_EX_OK)
-    return DL_EX_ERROR;
-
-  if ((i = lstat (realpath, &lsb)) == 0 && lsb.st_size == 0)
-    unlink (realpath);
-
-  dotlock_unlock (realpath);
-
-  return (i == 0) ?  DL_EX_OK : DL_EX_ERROR;
-}
-
-
-/*
- * Check if a file can be locked at all.
- * 
- * The same comment as for dotlock_lock () applies here.
- * 
- */
-
-static int
-dotlock_try (void)
-{
-#ifdef USE_SETGID
-  struct stat sb;
-#endif
-
-  if (access (".", W_OK) == 0)
-    return DL_EX_OK;
-
-#ifdef USE_SETGID
-  if (stat (".", &sb) == 0)
-  {
-    if ((sb.st_mode & S_IWGRP) == S_IWGRP && sb.st_gid == MailGid)
-      return DL_EX_NEED_PRIVS;
-  }
-#endif
-
-  return DL_EX_IMPOSSIBLE;
-}