Various portability fixes which should help out HURD.  

The iterate_on_dir function in libe2p has been changed to be more
general, so it relies less on the layout of struct dirent.  We also
make sure the errno returned by the ioctl is returned by 
fgetversion() and fsetversion().

diff --git a/ChangeLog b/ChangeLog
index 1fc70bb..0e6ee3e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2002-07-14  Theodore Ts'o  <tytso@mit.edu>
+
+	* configure.in, configure: Remove test for the presence (or
+		absence of d_namlen in the struct dirent) and replace it
+		with a check for pathconf().  lib/e2p/iod.c now uses a
+		different technique for providing struct dirent
+		compatibility.
+
 2002-06-25  Theodore Ts'o  <tytso@mit.edu>
 
 	* configure.in, configure: Add --enable-htree and --enable-clear-htree
diff --git a/configure b/configure
index 5970878..f8c6bc2 100644
--- a/configure
+++ b/configure
@@ -4266,53 +4266,20 @@
 
 fi
 
-echo $ac_n "checking whether struct dirent has a d_namlen field""... $ac_c" 1>&6
-echo "configure:4271: checking whether struct dirent has a d_namlen field" >&5
-if eval "test \"`echo '$''{'e2fsprogs_cv_struct_d_namlen'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 4276 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <dirent.h>
-int main() {
-struct dirent de; de.d_namlen = 0;
-; return 0; }
-EOF
-if { (eval echo configure:4284: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
-  rm -rf conftest*
-  e2fsprogs_cv_struct_d_namlen=yes
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  e2fsprogs_cv_struct_d_namlen=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$e2fsprogs_cv_struct_d_namlen" 1>&6
-if test "$e2fsprogs_cv_struct_d_namlen" = yes; then
-  cat >> confdefs.h <<\EOF
-#define HAVE_DIRENT_NAMLEN 1
-EOF
-
-fi
 echo $ac_n "checking whether llseek declared in unistd.h""... $ac_c" 1>&6
-echo "configure:4304: checking whether llseek declared in unistd.h" >&5
+echo "configure:4271: checking whether llseek declared in unistd.h" >&5
 if eval "test \"`echo '$''{'e2fsprogs_cv_have_llseek_prototype'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4309 "configure"
+#line 4276 "configure"
 #include "confdefs.h"
 #include <unistd.h>
 int main() {
 extern int llseek(int);
 ; return 0; }
 EOF
-if { (eval echo configure:4316: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4283: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   e2fsprogs_cv_have_llseek_prototype=no
 else
@@ -4332,12 +4299,12 @@
 
 fi
 echo $ac_n "checking whether lseek64 declared in unistd.h""... $ac_c" 1>&6
-echo "configure:4336: checking whether lseek64 declared in unistd.h" >&5
+echo "configure:4303: checking whether lseek64 declared in unistd.h" >&5
 if eval "test \"`echo '$''{'e2fsprogs_cv_have_lseek64_prototype'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4341 "configure"
+#line 4308 "configure"
 #include "confdefs.h"
 #define _LARGEFILE_SOURCE
 #define _LARGEFILE64_SOURCE
@@ -4346,7 +4313,7 @@
 extern int lseek64(int);
 ; return 0; }
 EOF
-if { (eval echo configure:4350: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4317: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   e2fsprogs_cv_have_lseek64_prototype=no
 else
@@ -4374,7 +4341,7 @@
   echo "configure: warning: Cross-compiling, so cannot check type sizes; assuming short=2, int=4, long=4, long long=8" 1>&2
 fi
 echo $ac_n "checking size of short""... $ac_c" 1>&6
-echo "configure:4378: checking size of short" >&5
+echo "configure:4345: checking size of short" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4382,7 +4349,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4386 "configure"
+#line 4353 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 #include <sys/types.h>
@@ -4394,7 +4361,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:4398: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4365: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_short=`cat conftestval`
 else
@@ -4414,7 +4381,7 @@
 
 
 echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:4418: checking size of int" >&5
+echo "configure:4385: checking size of int" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4422,7 +4389,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4426 "configure"
+#line 4393 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 #include <sys/types.h>
@@ -4434,7 +4401,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:4438: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_int=`cat conftestval`
 else
@@ -4454,7 +4421,7 @@
 
 
 echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:4458: checking size of long" >&5
+echo "configure:4425: checking size of long" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4462,7 +4429,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4466 "configure"
+#line 4433 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 #include <sys/types.h>
@@ -4474,7 +4441,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:4478: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4445: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long=`cat conftestval`
 else
@@ -4494,7 +4461,7 @@
 
 
 echo $ac_n "checking size of long long""... $ac_c" 1>&6
-echo "configure:4498: checking size of long long" >&5
+echo "configure:4465: checking size of long long" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4502,7 +4469,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4506 "configure"
+#line 4473 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 #include <sys/types.h>
@@ -4514,7 +4481,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:4518: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4485: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long_long=`cat conftestval`
 else
@@ -4542,14 +4509,14 @@
 
 
 echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:4546: checking whether byte ordering is bigendian" >&5
+echo "configure:4513: checking whether byte ordering is bigendian" >&5
 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_bigendian=unknown
 # See if sys/param.h defines the BYTE_ORDER macro.
 cat > conftest.$ac_ext <<EOF
-#line 4553 "configure"
+#line 4520 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -4560,11 +4527,11 @@
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:4564: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4531: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   # It does; now see whether it defined to BIG_ENDIAN or not.
 cat > conftest.$ac_ext <<EOF
-#line 4568 "configure"
+#line 4535 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -4575,7 +4542,7 @@
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:4579: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4546: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_bigendian=yes
 else
@@ -4595,7 +4562,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4599 "configure"
+#line 4566 "configure"
 #include "confdefs.h"
 main () {
   /* Are we little or big endian?  From Harbison&Steele.  */
@@ -4608,7 +4575,7 @@
   exit (u.c[sizeof (long) - 1] == 1);
 }
 EOF
-if { (eval echo configure:4612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4579: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_bigendian=no
 else
@@ -4632,19 +4599,19 @@
 fi
 
 echo $ac_n "checking whether struct stat has a st_flags field""... $ac_c" 1>&6
-echo "configure:4636: checking whether struct stat has a st_flags field" >&5
+echo "configure:4603: checking whether struct stat has a st_flags field" >&5
 if eval "test \"`echo '$''{'e2fsprogs_cv_struct_st_flags'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4641 "configure"
+#line 4608 "configure"
 #include "confdefs.h"
 #include <sys/stat.h>
 int main() {
 struct stat stat; stat.st_flags = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:4648: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4615: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   e2fsprogs_cv_struct_st_flags=yes
 else
@@ -4659,19 +4626,19 @@
 echo "$ac_t""$e2fsprogs_cv_struct_st_flags" 1>&6
 if test "$e2fsprogs_cv_struct_st_flags" = yes; then
   echo $ac_n "checking whether st_flags field is useful""... $ac_c" 1>&6
-echo "configure:4663: checking whether st_flags field is useful" >&5
+echo "configure:4630: checking whether st_flags field is useful" >&5
   if eval "test \"`echo '$''{'e2fsprogs_cv_struct_st_flags_immut'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4668 "configure"
+#line 4635 "configure"
 #include "confdefs.h"
 #include <sys/stat.h>
 int main() {
 struct stat stat; stat.st_flags |= UF_IMMUTABLE;
 ; return 0; }
 EOF
-if { (eval echo configure:4675: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4642: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   e2fsprogs_cv_struct_st_flags_immut=yes
 else
@@ -4691,15 +4658,15 @@
 
   fi
 fi
-for ac_func in chflags getrusage llseek lseek64 open64 getmntinfo strcasecmp srandom fchown mallinfo fdatasync strnlen sysconf
+for ac_func in chflags getrusage llseek lseek64 open64 getmntinfo strcasecmp srandom fchown mallinfo fdatasync strnlen sysconf pathconf
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4698: checking for $ac_func" >&5
+echo "configure:4665: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4703 "configure"
+#line 4670 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4722,7 +4689,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:4726: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4693: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4748,7 +4715,7 @@
 
 SOCKET_LIB=''
 echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6
-echo "configure:4752: checking for socket in -lsocket" >&5
+echo "configure:4719: checking for socket in -lsocket" >&5
 ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -4756,7 +4723,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4760 "configure"
+#line 4727 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -4767,7 +4734,7 @@
 socket()
 ; return 0; }
 EOF
-if { (eval echo configure:4771: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4738: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4789,12 +4756,12 @@
 
 
 echo $ac_n "checking for optreset""... $ac_c" 1>&6
-echo "configure:4793: checking for optreset" >&5
+echo "configure:4760: checking for optreset" >&5
 if eval "test \"`echo '$''{'ac_cv_have_optreset'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4798 "configure"
+#line 4765 "configure"
 #include "confdefs.h"
 #include <unistd.h>
 EOF
@@ -4866,20 +4833,20 @@
 
 
 echo $ac_n "checking whether linker accepts -static""... $ac_c" 1>&6
-echo "configure:4870: checking whether linker accepts -static" >&5
+echo "configure:4837: checking whether linker accepts -static" >&5
 if eval "test \"`echo '$''{'ac_cv_e2fsprogs_use_static'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   SAVE_LDFLAGS=$LDFLAGS; LDFLAGS="$LDFLAGS -static"
 cat > conftest.$ac_ext <<EOF
-#line 4876 "configure"
+#line 4843 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 int main() {
 fflush(stdout);
 ; return 0; }
 EOF
-if { (eval echo configure:4883: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4850: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_e2fsprogs_use_static=yes
 else
diff --git a/configure.in b/configure.in
index cfad88e..11035b7 100644
--- a/configure.in
+++ b/configure.in
@@ -494,23 +494,6 @@
 AC_CHECK_HEADERS(stdlib.h unistd.h stdarg.h errno.h malloc.h mntent.h paths.h dirent.h getopt.h setjmp.h signal.h termios.h linux/fd.h linux/major.h sys/disklabel.h sys/ioctl.h sys/mkdev.h sys/mount.h sys/sockio.h sys/sysmacros.h sys/time.h sys/stat.h sys/types.h net/if.h netinet/in.h)
 AC_FUNC_VPRINTF
 dnl
-dnl See if struct dirent has a d_namlen field (like bsd systems), implying
-dnl that the actual length of the structure may be grater than the declared
-dnl length. 
-dnl
-AC_MSG_CHECKING(whether struct dirent has a d_namlen field)
-AC_CACHE_VAL(e2fsprogs_cv_struct_d_namlen,
-	AC_TRY_COMPILE(
-[#include <sys/types.h>
-#include <dirent.h>],
-		[struct dirent de; de.d_namlen = 0;],
-		[e2fsprogs_cv_struct_d_namlen=yes],
-		[e2fsprogs_cv_struct_d_namlen=no]))
-AC_MSG_RESULT($e2fsprogs_cv_struct_d_namlen)
-if test "$e2fsprogs_cv_struct_d_namlen" = yes; then
-  AC_DEFINE(HAVE_DIRENT_NAMLEN)
-fi
-dnl
 dnl Check to see if llseek() is declared in unistd.h.  On some libc's 
 dnl it is, and on others it isn't..... Thank you glibc developers....
 dnl
@@ -595,7 +578,7 @@
 	  AC_DEFINE(HAVE_STAT_FLAGS)
   fi
 fi
-AC_CHECK_FUNCS(chflags getrusage llseek lseek64 open64 getmntinfo strcasecmp srandom fchown mallinfo fdatasync strnlen sysconf)
+AC_CHECK_FUNCS(chflags getrusage llseek lseek64 open64 getmntinfo strcasecmp srandom fchown mallinfo fdatasync strnlen sysconf pathconf)
 dnl
 dnl Check to see if -lsocket is required (solaris) to make something
 dnl that uses socket() to compile; this is needed for the UUID library
diff --git a/lib/e2p/ChangeLog b/lib/e2p/ChangeLog
index 9df2ee4..3a81898 100644
--- a/lib/e2p/ChangeLog
+++ b/lib/e2p/ChangeLog
@@ -1,3 +1,14 @@
+2002-07-14  Theodore Ts'o  <tytso@mit.edu>
+
+	* fsetversion.c (fsetversion), fgetversion.c, fgetversion.c: Save
+		errno if the ioctl fails, and restore it just before we
+		return.
+
+	* iod.c (iterate_on_dir): Rewrite function to make it more
+		portable.  We now make much fewer assumptions about nature
+		and layout of struct dirent, which will hopefully help
+		things on the Hurd.
+
 2002-06-15  Theodore Ts'o  <tytso@mit.edu>
 
 	* pf.c: Changed "compressed dirty flag" from 'D' to 'Z'.  Add
diff --git a/lib/e2p/fgetversion.c b/lib/e2p/fgetversion.c
index b934c93..404258a 100644
--- a/lib/e2p/fgetversion.c
+++ b/lib/e2p/fgetversion.c
@@ -37,14 +37,18 @@
 int fgetversion (const char * name, unsigned long * version)
 {
 #if HAVE_EXT2_IOCTLS
-	int fd, r, ver;
+	int fd, r, ver, save_errno = 0;
 
 	fd = open (name, OPEN_FLAGS);
 	if (fd == -1)
-		return - 1;
+		return -1;
 	r = ioctl (fd, EXT2_IOC_GETVERSION, &ver);
+	if (r == -1)
+		save_errno = errno;
 	*version = ver;
 	close (fd);
+	if (save_errno)
+		errno = save_errno;
 	return r;
 #else /* ! HAVE_EXT2_IOCTLS */
 	extern int errno;
diff --git a/lib/e2p/fsetversion.c b/lib/e2p/fsetversion.c
index 597a4bc..0ba41dc 100644
--- a/lib/e2p/fsetversion.c
+++ b/lib/e2p/fsetversion.c
@@ -37,14 +37,18 @@
 int fsetversion (const char * name, unsigned long version)
 {
 #if HAVE_EXT2_IOCTLS
-	int fd, r, ver;
+	int fd, r, ver, save_errno = 0;
 
 	fd = open (name, OPEN_FLAGS);
 	if (fd == -1)
 		return -1;
 	ver = (int) version;
 	r = ioctl (fd, EXT2_IOC_SETVERSION, &ver);
+	if (r == -1)
+		save_errno = errno;
 	close (fd);
+	if (save_errno)
+		errno = save_errno;
 	return r;
 #else /* ! HAVE_EXT2_IOCTLS */
 	extern int errno;
diff --git a/lib/e2p/iod.c b/lib/e2p/iod.c
index 7b02a7f..c5d34cd 100644
--- a/lib/e2p/iod.c
+++ b/lib/e2p/iod.c
@@ -15,52 +15,54 @@
  */
 
 #include "e2p.h"
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 
 int iterate_on_dir (const char * dir_name,
 		    int (*func) (const char *, struct dirent *, void *),
 		    void * private)
 {
 	DIR * dir;
-#if HAVE_DIRENT_NAMELEN
-	/* Declare DE_BUF with some extra room for the name.  */
-	char de_buf[sizeof (struct dirent) + 32];
-	struct dirent *de = (struct dirent *)&de_buf;
-#else
-	struct dirent de_buf, *de = &de_buf;
+	struct dirent *de, *dep;
+	int	max_len = -1, len;
+
+#if HAVE_PATHCONF && defined(_PC_NAME_MAX) 
+	max_len = pathconf(dir_name, _PC_NAME_MAX);
 #endif
-	struct dirent *dep;
+	if (max_len == -1) {
+#ifdef _POSIX_NAME_MAX
+		max_len = _POSIX_NAME_MAX;
+#else
+#ifdef NAME_MAX
+		max_len = NAME_MAX;
+#else
+		max_len = 256;
+#endif /* NAME_MAX */
+#endif /* _POSIX_NAME_MAX */
+	}
+	max_len += sizeof(struct dirent);
+
+	de = malloc(max_len+1);
+	if (!de)
+		return -1;
+	memset(de, 0, max_len+1);
 
 	dir = opendir (dir_name);
-	if (dir == NULL)
+	if (dir == NULL) {
+		free(de);
 		return -1;
-	while ((dep = readdir (dir)))
-	{
-#if HAVE_DIRENT_NAMELEN
-	  /* See if there's enough room for this entry in DE, and grow if
-	     not.  */
-	  if (de_len < dep->d_reclen)
-	    {
-	      de_len = dep->d_reclen + 32;
-	      de =
-		(de == (struct dirent *)&de_buf
-		 ? malloc (de_len)
-		 : realloc (de, de_len));
-	      if (de == NULL)
-		{
-		  errno = ENOMEM;
-		  return -1;
-		}
-	    }
-	  memcpy (de, dep, dep->d_reclen);
-#else
-	  *de = *dep;
-#endif
-	  (*func) (dir_name, de, private);
 	}
-#if HAVE_DIRENT_NAMELEN
-	if (de != (struct dirent *)&de_buf)
-	  free (de);
-#endif
-	closedir (dir);
+	while ((dep = readdir (dir))) {
+		len = dep->d_reclen;
+		if (len < (sizeof(struct dirent)))
+			len = sizeof(struct dirent);
+		if (len > max_len)
+			len = max_len;
+		memcpy(de, dep, len);
+		(*func) (dir_name, de, private);
+	}
+	free(de);
+	closedir(dir);
 	return 0;
 }