]> arthur.barton.de Git - netatalk.git/commitdiff
Integrate talloc from Samba, cleanup configure functions checks
authorFrank Lahm <franklahm@googlemail.com>
Mon, 17 Jan 2011 16:12:19 +0000 (17:12 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Mon, 17 Jan 2011 16:12:19 +0000 (17:12 +0100)
33 files changed:
configure.in
etc/afpd/file.c
etc/afpd/filedir.c
etc/afpd/gettok.c
etc/afpd/nfsquota.c
etc/afpd/quota.c
etc/afpd/uam.c
etc/afpd/unix.c
etc/afpd/volume.c
etc/uams/uams_gss.c
etc/uams/uams_guest.c
etc/uams/uams_krb4/uams_krb4.c
etc/uams/uams_pam.c
etc/uams/uams_passwd.c
etc/uams/uams_randnum.c
include/atalk/compat.h
include/atalk/talloc.h [new file with mode: 0644]
include/atalk/util.h
libatalk/Makefile.am
libatalk/compat/Makefile.am
libatalk/compat/misc.c [new file with mode: 0644]
libatalk/compat/snprintf.c [deleted file]
libatalk/compat/strcasecmp.c [deleted file]
libatalk/compat/strdup.c [deleted file]
libatalk/compat/strlcpy.c [new file with mode: 0644]
libatalk/compat/strstr.c [deleted file]
libatalk/talloc/Makefile.am [new file with mode: 0644]
libatalk/talloc/talloc.c [new file with mode: 0644]
libatalk/unicode/charcnv.c
libatalk/util/Makefile.am
libatalk/util/fault.c
libatalk/util/strcasestr.c [deleted file]
libatalk/util/strlcpy.c [deleted file]

index aeff81340e784ad8f19ba6b16c2f6e2fe5ca8495..293202d300b95efae4412d6db22d5ef521d81d46 100644 (file)
@@ -23,14 +23,23 @@ AC_PROG_GREP
 AC_PROG_PS
 AM_PROG_CC_C_O
 
+dnl Request SUSv3 standard interfaces plus anything else the platform may have
+CFLAGS="$CFLAGS -D_XOPEN_SOURCE=600 -D__EXTENSIONS__ -D_GNU_SOURCE"
+
 dnl Checks for header files.
 AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(fcntl.h limits.h stdint.h strings.h time.h sys/param.h sys/fcntl.h sys/file.h sys/ioctl.h sys/time.h sys/mnttab.h sys/statvfs.h sys/stat.h sys/vfs.h mntent.h syslog.h unistd.h termios.h sys/termios.h netdb.h sgtty.h ufs/quota.h mount.h statfs.h sys/types.h dlfcn.h errno.h sys/errno.h sys/uio.h langinfo.h locale.h sys/filio.h)
+AC_CHECK_HEADERS(fcntl.h limits.h stdint.h strings.h time.h stdarg.h)
+AC_CHECK_HEADERS(mntent.h syslog.h unistd.h termios.h ufs/quota.h)
+AC_CHECK_HEADERS(netdb.h sgtty.h mount.h statfs.h dlfcn.h errno.h langinfo.h locale.h)
+AC_CHECK_HEADERS(sys/param.h sys/fcntl.h sys/file.h sys/ioctl.h sys/time.h)
+AC_CHECK_HEADERS(sys/mnttab.h sys/statvfs.h sys/stat.h sys/vfs.h)
+AC_CHECK_HEADERS(sys/termios.h sys/types.h sys/errno.h sys/uio.h sys/filio.h)
 AC_CHECK_HEADER(sys/cdefs.h,,
        AC_MSG_RESULT([enabling generic cdefs.h from tree])
        CFLAGS="-I\$(top_srcdir)/sys/generic $CFLAGS"
 )
+
 AC_CHECK_HEADERS([sys/mount.h], , , 
 [#ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
@@ -59,26 +68,18 @@ if test x"$libltdl_cv_need_uscore" = xyes; then
     AC_DEFINE(DLSYM_PREPEND_UNDERSCORE, 1, [BSD compatibility macro])
 fi
 
-dnl Checks for library functions.
-AC_TYPE_GETGROUPS
-AC_PROG_GCC_TRADITIONAL
-AC_FUNC_MEMCMP
-AC_HEADER_MAJOR
-AC_FUNC_MMAP
-AC_TYPE_SIGNAL
-AC_FUNC_UTIME_NULL
-AC_FUNC_WAIT3
-AC_CHECK_FUNCS(getcwd gethostname gettimeofday getusershell mkdir rmdir select socket strdup strcasestr strstr strtoul strchr memcpy)
-AC_CHECK_FUNCS(backtrace_symbols setlocale nl_langinfo strlcpy strlcat setlinebuf dirfd pselect access pread pwrite)
-AC_CHECK_FUNCS(waitpid getcwd strdup strndup strnlen strtoul strerror chown fchown chmod fchmod chroot link mknod mknod64)
-AC_CHECK_FUNC(renameat, AC_DEFINE([_ATFILE_SOURCE], 1, AT file source)) 
+dnl Special hecks
 AC_CHECK_MEMBERS(struct tm.tm_gmtoff,,, [#include <time.h>])
 
-AC_CHECK_FUNC(gethostbyname,,[AC_CHECK_LIB(nsl,gethostbyname)])
-AC_CHECK_FUNC(connect,,[AC_CHECK_LIB(socket,connect)])
-dnl search for necessary libs for libpthread stuff
-AC_SEARCH_LIBS(pthread_sigmask, pthread,, 
-               [AC_MSG_ERROR([cannot find pthread_sigmask in libc or libpthread])])
+dnl these tests have been comfirmed to be needed in 2011
+AC_CHECK_FUNC(renameat, AC_DEFINE([_ATFILE_SOURCE], 1, AT file source)) 
+AC_CHECK_FUNCS(backtrace_symbols dirfd getusershell pread pwrite pselect)
+AC_CHECK_FUNCS(setlinebuf strlcat strlcpy strnlen)
+
+dnl search for necessary libraries
+AC_SEARCH_LIBS(gethostbyname, nsl)
+AC_SEARCH_LIBS(connect, socket)
+AC_SEARCH_LIBS(pthread_sigmask, pthread,,[AC_MSG_ERROR([missing pthread_sigmask])])
 if test x"$ac_cv_search_pthread_sigmask" != x"none required" ; then
    PTHREAD_LIBS=$ac_cv_search_pthread_sigmask
 fi
@@ -1253,8 +1254,6 @@ dnl --------------------- Netatalk Webmin
 NETATALK_WEBMIN
 
 dnl --------------------- last minute substitutions
-dnl Request SUSv3 standard interfaces
-CFLAGS="$CFLAGS -D_XOPEN_SOURCE=600 -D__EXTENSIONS__"
 AC_SUBST(LIBS)
 AC_SUBST(CFLAGS)
 AC_SUBST(OVERWRITE_CONFIG)
@@ -1349,6 +1348,7 @@ AC_OUTPUT([Makefile
        libatalk/nbp/Makefile
        libatalk/netddp/Makefile
        libatalk/util/Makefile
+       libatalk/talloc/Makefile
        libatalk/tdb/Makefile
        libatalk/unicode/Makefile
        libatalk/unicode/charsets/Makefile
index ebe61e12885cbc6e112078fdd9d167bc00b99537..e827134ab1750e14af420a1a2ccb27c872e96008 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 
-/* STDC check */
-#if STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
-
 #include <utime.h>
 #include <errno.h>
 #include <sys/param.h>
index be7056a796ab9c0729d1b8d4307c54ca5f3818d8..ebde9655e6ef754816621813d6912eee60b0909c 100644 (file)
@@ -9,21 +9,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-/* STDC check */
-#if STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
-
 #ifdef HAVE_STRINGS_H
 #include <strings.h>
 #endif
index d4e4d8f58e30f6cac089ed11d07cdb6d03dd5296..f8ef210a43361c04c3cd1a29a77e55cd0a754fda 100644 (file)
 #endif /* HAVE_CONFIG_H */
 
 #include <sys/param.h>
-
-/* STDC check */
-#if STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
-
 #include <ctype.h>
 #include <pwd.h>
 
index e3ad5ddc164a0c2725f4e841552cc6a03024a95d..60622733cd79ba3085b6f3003bbf4bd611f25d63 100644 (file)
 
 #ifndef NO_QUOTA_SUPPORT
 #include <stdio.h>
-/* STDC check */
-#if STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/param.h> /* for DEV_BSIZE */
index 9992948c1af20576823eca7abb8243f020cca49d..06008c20f6140a627ad1aab9ff308d7aceaea0ca 100644 (file)
 #include <string.h>
 #include <errno.h>
 #include <sys/types.h>
-/* STDC check */
-#if STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/param.h>
index 5c105e3181728d34aa85eed89680f8a1b7b5db31..8e247a248a423136613961c1a9199715196cbf44 100644 (file)
 
 #include <stdio.h>
 #include <stdlib.h>
-
-/* STDC check */
-#if STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
-
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif /* HAVE_UNISTD_H */
index 8f1fca20aa47e673425360a2d3a79389ed6ce256..b1ddfd919dd93c642b8390a1b84e044ca3ca7225 100644 (file)
@@ -9,24 +9,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-
-/* STDC check */
-#ifdef STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
-
 #include <errno.h>
 #include <limits.h>
 #include <sys/param.h>
index ccd4b68ebc21582e7256323f3a1e3441a788dc96..8967860503853a80510d4219fbe3ac6c074d7513 100644 (file)
 #ifdef HAVE_STRINGS_H
 #include <strings.h>
 #endif
-/* STDC check */
-#if STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
index 044dd278bac78dea2d88ac3e72e8555ccf440812..0560f5f79a065036473eeb873ba8006a6bf57b31 100644 (file)
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif /* HAVE_UNISTD_H */
-
-/* STDC check */
-#if STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
-
 #include <errno.h>
+
 #include <atalk/logger.h>
 #include <atalk/afp.h>
 #include <atalk/uam.h>
index 0b5019e0e7e4d0214cb4db90250553742e138210..7a2482d6ca50fb57071806d2c701561aaede3d53 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
-
-/* STDC check */
-#if STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
-
 #include <pwd.h>
-#include <atalk/logger.h>
 
+#include <atalk/logger.h>
 #include <atalk/afp.h>
 #include <atalk/uam.h>
 #include <atalk/util.h>
index ff7c2c0a4767e9ac7af0eee3394b59173fc08603..1d2727a8fa4a76f5cc90313f02a2fa10a812870c 100644 (file)
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <limits.h>
-
-/* STDC check */
-#if STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
-
 #include <ctype.h>
 #include <pwd.h>
 #include <atalk/logger.h>
index 46ce0d51a43d50d020b5737bb5797f9db2364cc4..a374cc336e2e9c07774820e8c5a0c247c21ccd46 100644 (file)
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif /* HAVE_UNISTD_H */
-
-/* STDC check */
-#if STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
-
 #include <atalk/logger.h>
 
 #ifdef HAVE_SECURITY_PAM_APPL_H
index d026a50dab1ea8909d518e7a13a3c84463c59f14..507cb04f791bfcdbe0badd632f8f04040ac182e7 100644 (file)
 
 #include <stdio.h>
 #include <stdlib.h>
-/* STDC check */
-#if STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif /* HAVE_UNISTD_H */
index 3d3a5bb9b72afc9bf267a03bb3682d9288f28d1f..c9a275ba792d2394befb2760b2bd095794c8ff8b 100644 (file)
 
 #include <stdio.h>
 #include <stdlib.h>
-
-/* STDC check */
-#if STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
-
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif /* HAVE_UNISTD_H */
index 429955349f74c9ca2572357c68851f5f359c1167..f66c3a3145977960869eb6c17ad76aba39ac8c6e 100644 (file)
@@ -9,88 +9,22 @@
 #include <sys/cdefs.h>
 #include <signal.h>
 
-#ifdef __svr4__
-/*
- * SunOS 5 (solaris) has SA_RESTART, but no SA_INTERRUPT.
- */
-#ifndef SA_INTERRUPT
-#define SA_INTERRUPT   0
-#endif
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-extern int flock (int, int);
-extern int inet_aton (const char *, struct in_addr *);
-#else /* __svr4__ */
-
-#ifdef sun
-/*
- * SunOS 4 has SA_INTERRUPT, but no SA_RESTART.
- */
-#ifndef SA_RESTART
-#define SA_RESTART     0
-#endif
-#endif /* sun */
-
-#endif /* __svr4__ */
-
-#ifdef linux
-/*
- * Linux has SA_RESTART, but no SA_INTERRUPT.  Note that the documentation
- * seems to be wrong on several counts.  First, SA_ONESHOT is not the default,
- * and second, SA_RESTART does what you'd expect (the same as svr4) and has
- * nothing to do with SA_ONESHOT.
- */
-#ifndef SA_INTERRUPT
-#define SA_INTERRUPT   0
-#endif /* SA_INTERRUPT */
-#endif /* linux */
-
-#ifdef ultrix 
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-/*
- * Here's the really confusing one...  Under Ultrix, sigaction() works just
- * like sigvec(), except that SV_INTERRUPT is always set.  Hence, there is
- * no SA_INTERRUPT flag.  Unfortunately, there's also no SA_RESTART, so
- * there's no way to suppress the interrupt.  Sigh.
- */
-#ifndef SA_INTERRUPT
-#define SA_INTERRUPT   0
-#endif
-#ifndef SA_RESTART
-#define SA_RESTART     0
-#endif
-
-extern char *strdup (const char *);
-extern int inet_aton (const char *, struct in_addr *);
-#endif /* ultrix */
-
-#ifdef BSD4_4
-#ifndef SA_INTERRUPT
-#define SA_INTERRUPT   0
-#endif
-#endif /* BSD4_4 */
+#include "config.h"
 
 #if defined(ultrix) || defined(_IBMR2) || defined(NEED_GETUSERSHELL)
 extern char *getusershell (void);
 #endif
 
 #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
-#include <stdio.h>
-#include <stdarg.h>
-#endif
-
-#ifndef HAVE_SNPRINTF
+# include <stdio.h>
+# include <stdarg.h>
+# ifndef HAVE_SNPRINTF
 int snprintf (char *str,size_t count,const char *fmt,...);
-#endif
+# endif
 
-#ifndef HAVE_VSNPRINTF
+# ifndef HAVE_VSNPRINTF
 int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
+# endif
 #endif
 
 /* OpenBSD */
@@ -103,3 +37,25 @@ extern int pselect(int, fd_set * restrict, fd_set * restrict,
                    fd_set * restrict, const struct timespec * restrict,
                    const sigset_t * restrict);
 #endif
+
+#ifndef HAVE_FLOCK
+extern int flock (int, int);
+#endif
+
+#ifndef HAVE_INET_ATON
+struct in_addr;
+extern int inet_aton(const char *, struct in_addr *);
+#endif
+
+#ifndef HAVE_STRNLEN
+extern size_t strnlen(const char *s, size_t n);
+#endif
+
+#ifndef HAVE_STRLCPY
+extern size_t strlcpy (char *, const char *, size_t);
+#endif
+#ifndef HAVE_STRLCAT
+extern size_t strlcat (char *, const char *, size_t);
+#endif
+
diff --git a/include/atalk/talloc.h b/include/atalk/talloc.h
new file mode 100644 (file)
index 0000000..f549a17
--- /dev/null
@@ -0,0 +1,202 @@
+#ifndef _TALLOC_H_
+#define _TALLOC_H_
+/* 
+   Unix SMB/CIFS implementation.
+   Samba temporary memory allocation functions
+
+   Copyright (C) Andrew Tridgell 2004-2005
+   Copyright (C) Stefan Metzmacher 2006
+   
+     ** NOTE! The following LGPL license applies to the talloc
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+   
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#define TALLOC_VERSION_MAJOR 2
+#define TALLOC_VERSION_MINOR 0
+
+int talloc_version_major(void);
+int talloc_version_minor(void);
+
+/* this is only needed for compatibility with the old talloc */
+typedef void TALLOC_CTX;
+
+/*
+  this uses a little trick to allow __LINE__ to be stringified
+*/
+#ifndef __location__
+#define __TALLOC_STRING_LINE1__(s)    #s
+#define __TALLOC_STRING_LINE2__(s)   __TALLOC_STRING_LINE1__(s)
+#define __TALLOC_STRING_LINE3__  __TALLOC_STRING_LINE2__(__LINE__)
+#define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__
+#endif
+
+#ifndef TALLOC_DEPRECATED
+#define TALLOC_DEPRECATED 0
+#endif
+
+#ifndef PRINTF_ATTRIBUTE
+#if (__GNUC__ >= 3)
+/** Use gcc attribute to check printf fns.  a1 is the 1-based index of
+ * the parameter containing the format, and a2 the index of the first
+ * argument. Note that some gcc 2.x versions don't handle this
+ * properly **/
+#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
+#else
+#define PRINTF_ATTRIBUTE(a1, a2)
+#endif
+#endif
+
+/* try to make talloc_set_destructor() and talloc_steal() type safe,
+   if we have a recent gcc */
+#if (__GNUC__ >= 3)
+#define _TALLOC_TYPEOF(ptr) __typeof__(ptr)
+#define talloc_set_destructor(ptr, function)                                 \
+       do {                                                                  \
+               int (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function);       \
+               _talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \
+       } while(0)
+/* this extremely strange macro is to avoid some braindamaged warning
+   stupidity in gcc 4.1.x */
+#define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal_loc((ctx),(ptr), __location__); __talloc_steal_ret; })
+#else
+#define talloc_set_destructor(ptr, function) \
+       _talloc_set_destructor((ptr), (int (*)(void *))(function))
+#define _TALLOC_TYPEOF(ptr) void *
+#define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal_loc((ctx),(ptr), __location__)
+#endif
+
+#define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference_loc((ctx),(ptr), __location__)
+#define talloc_move(ctx, ptr) (_TALLOC_TYPEOF(*(ptr)))_talloc_move((ctx),(void *)(ptr))
+
+/* useful macros for creating type checked pointers */
+#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
+#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__)
+#define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr)))
+
+#define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__)
+
+#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
+#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__)
+
+#define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type)
+#define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type)
+#define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__)
+#define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count)
+#define talloc_array_length(ctx) (talloc_get_size(ctx)/sizeof(*ctx))
+
+#define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type)
+#define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__)
+
+#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__)
+
+#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)
+#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
+#define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__)
+
+#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type)
+#define talloc_free(ctx) _talloc_free(ctx, __location__)
+
+
+#if TALLOC_DEPRECATED
+#define talloc_zero_p(ctx, type) talloc_zero(ctx, type)
+#define talloc_p(ctx, type) talloc(ctx, type)
+#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count)
+#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count)
+#define talloc_destroy(ctx) talloc_free(ctx)
+#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a))
+#endif
+
+#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
+
+/* The following definitions come from talloc.c  */
+void *_talloc(const void *context, size_t size);
+void *talloc_pool(const void *context, size_t size);
+void _talloc_set_destructor(const void *ptr, int (*_destructor)(void *));
+int talloc_increase_ref_count(const void *ptr);
+size_t talloc_reference_count(const void *ptr);
+void *_talloc_reference_loc(const void *context, const void *ptr, const char *location);
+int talloc_unlink(const void *context, void *ptr);
+const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
+void talloc_set_name_const(const void *ptr, const char *name);
+void *talloc_named(const void *context, size_t size, 
+                  const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
+void *talloc_named_const(const void *context, size_t size, const char *name);
+const char *talloc_get_name(const void *ptr);
+void *talloc_check_name(const void *ptr, const char *name);
+void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location);
+void *talloc_parent(const void *ptr);
+const char *talloc_parent_name(const void *ptr);
+void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
+int _talloc_free(void *ptr, const char *location);
+void talloc_free_children(void *ptr);
+void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name);
+void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location);
+void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr);
+void *_talloc_move(const void *new_ctx, const void *pptr);
+size_t talloc_total_size(const void *ptr);
+size_t talloc_total_blocks(const void *ptr);
+void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
+                           void (*callback)(const void *ptr,
+                                            int depth, int max_depth,
+                                            int is_ref,
+                                            void *private_data),
+                           void *private_data);
+void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f);
+void talloc_report_full(const void *ptr, FILE *f);
+void talloc_report(const void *ptr, FILE *f);
+void talloc_enable_null_tracking(void);
+void talloc_enable_null_tracking_no_autofree(void);
+void talloc_disable_null_tracking(void);
+void talloc_enable_leak_report(void);
+void talloc_enable_leak_report_full(void);
+void *_talloc_zero(const void *ctx, size_t size, const char *name);
+void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name);
+void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name);
+void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name);
+void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name);
+void *talloc_realloc_fn(const void *context, void *ptr, size_t size);
+void *talloc_autofree_context(void);
+size_t talloc_get_size(const void *ctx);
+void *talloc_find_parent_byname(const void *ctx, const char *name);
+void talloc_show_parents(const void *context, FILE *file);
+int talloc_is_parent(const void *context, const void *ptr);
+
+char *talloc_strdup(const void *t, const char *p);
+char *talloc_strdup_append(char *s, const char *a);
+char *talloc_strdup_append_buffer(char *s, const char *a);
+
+char *talloc_strndup(const void *t, const char *p, size_t n);
+char *talloc_strndup_append(char *s, const char *a, size_t n);
+char *talloc_strndup_append_buffer(char *s, const char *a, size_t n);
+
+char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
+char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
+char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
+
+char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
+char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
+char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
+
+void talloc_set_abort_fn(void (*abort_fn)(const char *reason));
+void talloc_set_log_fn(void (*log_fn)(const char *message));
+void talloc_set_log_stderr(void);
+
+#endif
index ba55bc9b0f381d66089e9d35e10046143e984951..c94306d23febdc7f19d2f632b543919cd68c0ff6 100644 (file)
 #define AFP_ASSERT(b)
 #endif /* NDEBUG */
 
+#ifndef MIN
+#define MIN(a, b)  ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a, b)  ((a) > (b) ? (a) : (b))
+#endif
+
 #define STRCMP(a,b,c) (strcmp(a,c) b 0)
 
 #ifdef WITH_SENDFILE
@@ -69,19 +77,6 @@ extern void fault_setup        (void (*fn)(void *));
 extern void netatalk_panic(const char *why);
 #define server_unlock(x)  (unlink(x))
 
-/* strlcpy and strlcat are used by pam modules */
-#ifndef UAM_MODULE_EXPORT
-#define UAM_MODULE_EXPORT 
-#endif
-
-#ifndef HAVE_STRLCPY
-UAM_MODULE_EXPORT size_t strlcpy (char *, const char *, size_t);
-#endif
-#ifndef HAVE_STRLCAT
-UAM_MODULE_EXPORT size_t strlcat (char *, const char *, size_t);
-#endif
-
 #ifndef HAVE_DLFCN_H
 extern void *mod_open    (const char *);
 extern void *mod_symbol  (void *, const char *);
index a70237318ff84c457c5cf8dbae43b39c12123a4a..ab44b3d6ef39437b79ae049892b3209198f37f20 100644 (file)
@@ -1,7 +1,7 @@
 
 # Makefile.am for libatalk/
 
-SUBDIRS = acl adouble bstring compat cnid dsi tdb util unicode vfs
+SUBDIRS = acl adouble bstring compat cnid dsi talloc tdb util unicode vfs
 
 lib_LTLIBRARIES = libatalk.la
 
index 515681d38daf59c11643e094a4136b523599bb13..2338cf39721da572cc2ad4e0d77de2525d97e4c8 100644 (file)
@@ -5,4 +5,6 @@ noinst_LTLIBRARIES = libcompat.la
 libcompat_la_SOURCES = \
        getusershell.c  \
        rquota_xdr.c    \
-       pselect.c
+       pselect.c               \
+       strlcpy.c               \
+       misc.c
diff --git a/libatalk/compat/misc.c b/libatalk/compat/misc.c
new file mode 100644 (file)
index 0000000..2fe6a7f
--- /dev/null
@@ -0,0 +1,15 @@
+#include <atalk/compat.h>
+
+#ifndef HAVE_STRNLEN
+size_t strnlen(const char *s, size_t max)
+{
+    size_t len;
+  
+    for (len = 0; len < max; len++) {
+        if (s[len] == '\0') {
+            break;
+        }
+    }
+    return len;  
+}
+#endif
diff --git a/libatalk/compat/snprintf.c b/libatalk/compat/snprintf.c
deleted file mode 100644 (file)
index eea7729..0000000
+++ /dev/null
@@ -1,1132 +0,0 @@
-/**************************************************************************
- * Copyright 1994-2000 Patrick Powell, San Diego, CA <papowell@astart.com>
- * 
- * Modified for Netatalk 2002/02/12 Burkhard Schmidt <bs@cpfs.mpg.de>
- **************************************************************************/
-
-/*
-   Overview:
-
-   plp_snprintf( char *buffer, int len, const char *format,...)
-   plp_unsafe_snprintf( char *buffer, int len, const char *format,...)
-     its horribly unsafe companion that does NOT protect you from
-     the printing of evil control characters,  but may be necessary
-     See the man page documentation below
-   
-   This version of snprintf was developed originally for printing
-   on a motley collection of specialized hardware that had NO IO
-   library.  Due to contractual restrictions,  a clean room implementation
-   of the printf() code had to be developed.
-   
-   The method chosen for printf was to be as paranoid as possible,
-   as these platforms had NO memory protection,  and very small
-   address spaces.  This made it possible to try to print
-   very long strings, i.e. - all of memory, very easily.  To guard
-   against this,  all printing was done via a buffer, generous enough
-   to hold strings,  but small enough to protect against overruns,
-   etc.
-   
-   Strangely enough,  this proved to be of immense importance when
-   SPRINTFing to a buffer on a stack...  The rest,  of course,  is
-   well known,  as buffer overruns in the stack are a common way to
-   do horrible things to operating systems, security, etc etc.
-   
-   This version of snprintf is VERY limited by modern standards.
-
-   Revision History:
-   First Released Version - 1994.  This version had NO comments.
-   First Released Version - 1994.  This version had NO comments.
-   Second Major Released Version - Tue May 23 10:43:44 PDT 2000
-    Configuration and other items changed.  Read this doc.
-    Treat this as a new version.
-   
-   COPYRIGHT AND TERMS OF USE:
-   
-   You may use, copy, distribute, or otherwise incorporate this software
-   and documentation into any product or other item,  provided that
-   the copyright in the documentation and source code as well as the
-   source code generated constant strings in the object, executable
-   or other code remain in place and are present in executable modules
-   or objects.
-   
-   You may modify this code as appropriate to your usage; however the
-   modified version must be identified by changing the various source
-   and object code identification strings as is appropriately noted
-   in the source code.
-   
-   The next include line is expected to work in conjunction with the
-   GNU CONFIGURE utility.  You  should define the following macros
-   appropriately:
-   
-   HAVE_STDARG_H - if the <stdargs.h> include file is available
-   HAVE_VARARG_H - if the <varargs.h> include file is available
-   
-   HAVE_STRERROR - if the strerror() routine is available.
-     If it is not available, then examine the lines containing
-     the tests below.  You may need to fiddle with HAVE_SYS_NERR
-   HAVE_SYS_ERRLIST
-   HAVE_DECL_SYS_ERRLIST
-   HAVE_SYS_NERR
-   HAVE_DECL_SYS_NERR
-   
-   HAVE_QUAD_T      - if the quad_t type is defined
-   HAVE_LONG_LONG   - if the long long type is defined
-   HAVE_LONG_DOUBLE - if the long double type is defined
-   
-     If you are using the GNU configure (autoconf) facility, add the
-     following line to the configure.in file, to force checking for the
-     quad_t and long long  data types:
-
-
-       AC_CHECK_FUNCS(strerror);
-       AC_CACHE_CHECK(for errno,
-       ac_cv_errno,
-       [
-       AC_TRY_LINK(,[extern int errno; return (errno);],
-               ac_cv_errno=yes, ac_cv_errno=no)
-       ])
-       if test "$ac_cv_errno" = yes; then
-               AC_DEFINE(HAVE_ERRNO)
-               AC_CACHE_CHECK(for errno declaration,
-               ac_cv_decl_errno,
-               [
-               AC_TRY_COMPILE([
-               #include <stdio.h>
-               #ifdef HAVE_STDLIB_H
-               #include <stdlib.h>
-               #endif
-               #ifdef HAVE_UNISTD_H
-               #include <unistd.h>
-               #endif
-               #ifdef HAVE_ERRNO_H
-               #include <errno.h>
-               ],[return(sys_nerr);],
-                       ac_cv_decl_errno=yes, ac_cv_decl_errno=no)
-               ])
-               if test "$ac_cv_decl_errno" = yes; then
-                       AC_DEFINE(HAVE_DECL_ERRNO)
-               fi;
-       fi
-
-       AC_CACHE_CHECK(for sys_nerr,
-       ac_cv_sys_nerr,
-       [
-       AC_TRY_LINK(,[extern int sys_nerr; return (sys_nerr);],
-               ac_cv_sys_nerr=yes, ac_cv_sys_nerr=no)
-       ])
-       if test "$ac_cv_sys_nerr" = yes; then
-               AC_DEFINE(HAVE_SYS_NERR)
-               AC_CACHE_CHECK(for sys_nerr declaration,
-               ac_cv_decl_sys_nerr,
-               [
-               AC_TRY_COMPILE([
-               #include <stdio.h>
-               #ifdef HAVE_STDLIB_H
-               #include <stdlib.h>
-               #endif
-               #ifdef HAVE_UNISTD_H
-               #include <unistd.h>
-               #endif],[return(sys_nerr);],
-               ac_cv_decl_sys_nerr_def=yes, ac_cv_decl_sys_nerr_def=no)
-               ])
-               if test "$ac_cv_decl_sys_nerr" = yes; then
-                       AC_DEFINE(HAVE_DECL_SYS_NERR)
-               fi
-       fi
-
-
-       AC_CACHE_CHECK(for sys_errlist array,
-       ac_cv_sys_errlist,
-       [AC_TRY_LINK(,[extern char *sys_errlist[];
-               sys_errlist[0];],
-               ac_cv_sys_errlist=yes, ac_cv_sys_errlist=no)
-       ])
-       if test "$ac_cv_sys_errlist" = yes; then
-               AC_DEFINE(HAVE_SYS_ERRLIST)
-               AC_CACHE_CHECK(for sys_errlist declaration,
-               ac_cv_sys_errlist_def,
-               [AC_TRY_COMPILE([
-               #include <stdio.h>
-               #include <errno.h>
-               #ifdef HAVE_STDLIB_H
-               #include <stdlib.h>
-               #endif
-               #ifdef HAVE_UNISTD_H
-               #include <unistd.h>
-               #endif],[char *s = sys_errlist[0]; return(*s);],
-               ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no)
-               ])
-               if test "$ac_cv_decl_sys_errlist" = yes; then
-                       AC_DEFINE(HAVE_DECL_SYS_ERRLIST)
-               fi
-       fi
-
-
-
-       AC_CACHE_CHECK(checking for long long,
-       ac_cv_long_long,
-       [
-       AC_TRY_COMPILE([
-       #include <stdio.h>
-       #include <sys/types.h>
-       ], [printf("%d",sizeof(long long));],
-       ac_cv_long_long=yes, ac_cv_long_long=no)
-       ])
-       if test $ac_cv_long_long = yes; then
-         AC_DEFINE(HAVE_LONG_LONG)
-       fi
-
-       AC_CACHE_CHECK(checking for long double,
-       ac_cv_long_double,
-       [
-       AC_TRY_COMPILE([
-       #include <stdio.h>
-       #include <sys/types.h>
-       ], [printf("%d",sizeof(long double));],
-       ac_cv_long_double=yes, ac_cv_long_double=no)
-       ])
-       if test $ac_cv_long_double = yes; then
-         AC_DEFINE(HAVE_LONG_DOUBLE)
-       fi
-
-       AC_CACHE_CHECK(checking for quad_t,
-       ac_cv_quad_t,
-       [
-       AC_TRY_COMPILE([
-       #include <stdio.h>
-       #include <sys/types.h>
-       ], [printf("%d",sizeof(quad_t));],
-       ac_cv_quad_t=yes, ac_cv_quad_t=no)
-       ])
-       if test $ac_cv_quad_t = yes; then
-         AC_DEFINE(HAVE_QUAD_T)
-       fi
-
-
-
-NAME
-     plp_snprintf, plp_vsnprintf - formatted output conversion
-
-SYNOPSIS
-     #include <stdio.h>
-     #include <stdarg.h>
-
-     int
-     plp_snprintf(const char *format, size_t size, va_list ap);
-     int
-     plp_unsafe_snprintf(const char *format, size_t size, va_list ap);
-
-     AKA snprintf and unsafe_snprintf in the documentation below
-
-     int
-     vsnprintf(char *str, size_t size, const char *format, va_list ap);
-     int
-     unsafe_vsnprintf(char *str, size_t size, const char *format, va_list ap);
-
-     AKA vsnprintf and unsafe_vsnprintf in the documentation below
-
-     (Multithreaded Safe)
-
-DESCRIPTION
-     The printf() family of functions produces output according to
-     a format as described below.  Snprintf(), and vsnprintf()
-     write to the character string str. These functions write the
-     output under the control of a format string that specifies
-     how subsequent arguments (or arguments accessed via the
-     variable-length argument facilities of stdarg(3))  are converted
-     for output.  These functions return the number of characters
-     printed (not including the trailing `\0' used to end output
-     to strings).  Snprintf() and vsnprintf() will write at most
-     size-1 of the characters printed into the output string (the
-     size'th character then gets the terminating `\0'); if the
-     return value is greater than or equal to the size argument,
-     the string was too short and some of the printed characters
-     were discarded.  The size or str may be given as zero to find
-     out how many characters are needed; in this case, the str
-     argument is ignored.
-
-     By default, the snprintf function will not format control
-     characters (except new line and tab) in strings.  This is a
-     safety feature that has proven to be extremely critical when
-     using snprintf for secure applications and when debugging.
-     If you MUST have control characters formatted or printed,
-     then use the unsafe_snprintf() and unsafe_vsnprintf() and on
-     your own head be the consequences.  You have been warned.
-
-     There is one exception to the comments above, and that is
-     the "%c" (character) format.  It brutally assumes that the
-     user will have performed the necessary 'isprint()' or other
-     checks and uses the integer value as a character.
-
-     The format string is composed of zero or more directives:
-     ordinary characters (not %), which are copied unchanged to
-     the output stream; and conversion specifications, each
-     of which results in fetching zero or more subsequent arguments.
-     Each conversion specification is introduced by the character
-     %. The arguments must correspond properly (after type promotion)
-     with the conversion specifier.  After the %, the following
-     appear in sequence:
-
-     o   Zero or more of the following flags:
-
-          -   A zero `0' character specifying zero padding.  For
-            all conversions except n, the converted value is padded
-            on the left with zeros rather than blanks.  If a
-            precision is given with a numeric conversion (d, i,
-            o, u, i, x, and X), the `0' flag is ignored.
-
-       -   A negative field width flag `-' indicates the converted
-            value is to be left adjusted on the field boundary.  Except
-            for n conversions, the converted value is padded on
-            the right with blanks, rather than on the left with
-            blanks or zeros.  A `-' overrides a `0' if both are
-            given.
-
-          -   A space, specifying that a blank should be left before
-            a positive number produced by a signed conversion (d, e, E, f,
-            g, G, or i).
-
-          -   A `+' character specifying that a sign always be placed
-            before a number produced by a signed conversion.  A `+' overrides
-            a space if both are used.
-
-     o   An optional decimal digit string specifying a minimum
-                field width.  If the converted value has fewer
-                characters than the field width, it will be padded
-                with spaces on the left (or right, if the
-                left-adjustment flag has been given) to fill out
-                the field width.
-
-     o   An optional precision, in the form of a period `.' followed
-                by an optional digit string.  If the digit string
-                is omitted, the precision is taken as zero.  This
-                gives the minimum number of digits to appear for
-                d, i, o, u, x, and X conversions, the number of
-                digits to appear after the decimal-point for e,
-                E, and f conversions, the maximum number of
-                significant digits for g and G conversions, or
-                the maximum number of characters to be printed
-                from a string for s conversions.
-
-     o   The optional character h, specifying that a following d,
-                i, o, u, x, or X conversion corresponds to a short
-                int or unsigned short int argument, or that a
-                following n conversion corresponds to a pointer
-                to a short int argument.
-
-     o   The optional character l (ell) specifying that a following
-                d, i, o, u, x, or X conversion applies to a pointer
-                to a long int or unsigned long int argument, or
-                that a following n conversion corresponds to a
-                pointer to a long int argument.
-
-     o   The optional character q, specifying that a following d,
-                i, o, u, x, or X conversion corresponds to a quad_t
-                or u_quad_t argument, or that a following n
-                conversion corresponds to a quad_t argument.
-         This value is always printed in HEX notation.  Tough.
-         quad_t's are an OS system implementation, and should
-         not be allowed.
-
-     o   The character L specifying that a following e, E, f, g,
-                or G conversion corresponds to a long double
-                argument.
-
-     o   A character that specifies the type of conversion to be applied.
-
-
-     A field width or precision, or both, may be indicated by an asterisk `*'
-     instead of a digit string.  In this case, an int argument supplies the
-     field width or precision.  A negative field width is treated as a left
-     adjustment flag followed by a positive field width; a negative precision
-     is treated as though it were missing.
-
-     The conversion specifiers and their meanings are:
-
-     diouxX  The int (or appropriate variant) argument is converted to signed
-                        decimal (d and i), unsigned octal (o), unsigned decimal
-                        (u), or unsigned hexadecimal (x and X) notation.  The
-                        letters abcdef are used for x conversions; the letters
-                        ABCDEF are used for X conversions.  The precision, if
-                        any, gives the minimum number of digits that must
-                        appear; if the converted value requires fewer digits,
-                        it is padded on the left with zeros.
-
-     eE      The double argument is rounded and converted in the style
-             [-]d.ddde+-dd where there is one digit before the decimal-point
-                        character and the number of digits after it is equal
-                        to the precision; if the precision is missing, it is
-                        taken as 6; if the precision is zero, no decimal-point
-                        character appears.  An E conversion uses the letter
-                        E (rather than e) to introduce the exponent.
-                        The exponent always contains at least two digits; if
-                        the value is zero, the exponent is 00.
-
-     f       The double argument is rounded and converted to decimal notation
-             in the style [-]ddd.ddd, where the number of digits after the
-             decimal-point character is equal to the precision specification.
-             If the precision is missing, it is taken as 6; if the precision
-             is explicitly zero, no decimal-point character appears.  If a
-             decimal point appears, at least one digit appears before it.
-
-     g       The double argument is converted in style f or e (or
-                        E for G conversions).  The precision specifies the
-                        number of significant digits.  If the precision is
-                        missing, 6 digits are given; if the precision is zero,
-                        it is treated as 1.  Style e is used if the exponent
-                        from its conversion is less than -4 or greater than
-                        or equal to the precision.  Trailing zeros are removed
-                        from the fractional part of the result; a decimal
-                        point appears only if it is followed by at least one
-                        digit.
-
-     c       The int argument is converted to an unsigned char,
-             and the resulting character is written.
-
-     s       The ``char *'' argument is expected to be a pointer to an array
-                        of character type (pointer to a string).  Characters
-                        from the array are written up to (but not including)
-                        a terminating NUL character; if a precision is
-                        specified, no more than the number specified are
-                        written.  If a precision is given, no null character
-                        need be present; if the precision is not specified,
-                        or is greater than the size of the array, the array
-                        must contain a terminating NUL character.
-
-     %       A `%' is written. No argument is converted. The complete
-             conversion specification is `%%'.
-
-     In no case does a non-existent or small field width cause truncation of a
-     field; if the result of a conversion is wider than the field width, the
-     field is expanded to contain the conversion result.
-
-EXAMPLES
-     To print a date and time in the form `Sunday, July 3, 10:02', where
-     weekday and month are pointers to strings:
-
-           #include <stdio.h>
-           fprintf(stdout, "%s, %s %d, %.2d:%.2d\n",
-                   weekday, month, day, hour, min);
-
-     To print pi to five decimal places:
-
-           #include <math.h>
-           #include <stdio.h>
-           fprintf(stdout, "pi = %.5f\n", 4 * atan(1.0));
-
-     To allocate a 128 byte string and print into it:
-
-           #include <stdio.h>
-           #include <stdlib.h>
-           #include <stdarg.h>
-           char *newfmt(const char *fmt, ...)
-           {
-                           char *p;
-                           va_list ap;
-                           if ((p = malloc(128)) == NULL)
-                                   return (NULL);
-                           va_start(ap, fmt);
-                           (void) vsnprintf(p, 128, fmt, ap);
-                           va_end(ap);
-                           return (p);
-           }
-
-SEE ALSO
-     printf(1),  scanf(3)
-
-STANDARDS
-     Turkey C Standardization and wimpy POSIX folks did not define
-     snprintf or vsnprintf().
-
-BUGS
-     The conversion formats %D, %O, and %U are not standard and are provided
-     only for backward compatibility.  The effect of padding the %p format
-     with zeros (either by the `0' flag or by specifying a precision), and the
-     benign effect (i.e., none) of the `#' flag on %n and %p conversions, as
-     well as other nonsensical combinations such as %Ld, are not standard;
-     such combinations should be avoided.
-
-     The typedef names quad_t and u_quad_t are infelicitous.
-
-*/
-
-
-#include "config.h"
-
-#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
-
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdlib.h>
-#if defined(HAVE_STRING_H)
-# include <string.h>
-#endif
-#if defined(HAVE_STRINGS_H)
-# include <strings.h>
-#endif
-#include <stdio.h>
-
-/*
- * For testing, define these values
- */
-#if 0
-#define HAVE_STDARG_H 1
-#define TEST 1
-#define HAVE_QUAD_T 1
-#endif
-
-/**** ENDINCLUDE ****/
-
-/*************************************************
- * KEEP THIS STRING - MODIFY AT THE END WITH YOUR REVISIONS
- * i.e. - the LOCAL REVISIONS part is for your use
- *************************************************/
- static char *const _id = "plp_snprintf V98.12.21 Copyright Patrick Powell 1988-2000 "
- "$Id: snprintf.c,v 1.2 2008-11-14 10:29:08 didg Exp $"
- " LOCAL REVISIONS: Modified for Netatalk 2002/02/12 Burkhard Schmidt";
-
-/* varargs declarations: */
-
-# undef HAVE_STDARGS    /* let's hope that works everywhere (mj) */
-# undef VA_LOCAL_DECL
-# undef VA_START
-# undef VA_SHIFT
-# undef VA_END
-
-#if defined(HAVE_STDARG_H)
-# include <stdarg.h>
-# define HAVE_STDARGS    /* let's hope that works everywhere (mj) */
-# define VA_LOCAL_DECL   va_list ap;
-# define VA_START(f)     va_start(ap, f)
-# define VA_SHIFT(v,t) ;       /* no-op for ANSI */
-# define VA_END          va_end(ap)
-#else
-# if defined(HAVE_VARARGS_H)
-#  include <varargs.h>
-#  undef HAVE_STDARGS
-#  define VA_LOCAL_DECL   va_list ap;
-#  define VA_START(f)     va_start(ap)         /* f is ignored! */
-#  define VA_SHIFT(v,t)        v = va_arg(ap,t)
-#  define VA_END               va_end(ap)
-# else
-XX ** NO VARARGS ** XX
-# endif
-#endif
-
-union value {
-#if defined(HAVE_QUAD_T)
-       quad_t qvalue;
-#endif
-#if defined(HAVE_LONG_LONG)
-       long long value;
-#else
-       long value;
-#endif
-       double dvalue;
-};
-
-#undef CVAL 
-#define CVAL(s) (*((unsigned char *)s))
-
-extern int errno;
- static char * plp_Errormsg ( int err, char *buffer );
- static void dopr( int visible_control, char **buffer, int *left,
-       const char *format, va_list args );
- static void fmtstr( int visible_control, char **buffer, int *left,
-       char *value, int ljust, int len, int zpad, int precision );
- static void fmtnum(  char **buffer, int *left,
-       union value *value, int base, int dosign,
-       int ljust, int len, int zpad, int precision );
-#if defined(HAVE_QUAD_T)
- static void fmtquad(  char **buffer, int *left,
-       union value *value, int base, int dosign,
-       int ljust, int len, int zpad, int precision );
-#endif
- static void fmtdouble( char **bufer, int *left,
-       int fmt, double value,
-       int ljust, int len, int zpad, int precision );
- static void dostr(  char **buffer, int *left, char *str );
- static void dopr_outch(  char **buffer, int *left, int c );
-
-int plp_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
-{
-       int left;
-       char *buffer;
-       if( count < 0 ) count = 0;
-       left = count;
-       if( count == 0 ) str = 0;
-       buffer = str;
-       dopr( 1, &buffer, &left, fmt, args );
-       /* fprintf(stderr,"str 0x%x, buffer 0x%x, count %d, left %d\n",
-               (int)str, (int)buffer, count, left ); */
-       if( str && count > 0 ){
-               if( left > 0 ){
-                       str[count-left] = 0;
-               } else {
-                       str[count-1] = 0;
-               }
-       }
-       return(count - left);
-}
-
-int plp_unsafe_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
-{
-       int left;
-       char *buffer;
-       if( count < 0 ) count = 0;
-       left = count;
-       if( count == 0 ) str = 0;
-       buffer = str;
-       dopr( 0, &buffer, &left, fmt, args );
-       /* fprintf(stderr,"str 0x%x, buffer 0x%x, count %d, left %d\n",
-               (int)str, (int)buffer, count, left ); */
-       if( str && count > 0 ){
-               if( left > 0 ){
-                       str[count-left] = 0;
-               } else {
-                       str[count-1] = 0;
-               }
-       }
-       return(count - left);
-}
-
-/* VARARGS3 */
-#ifdef HAVE_STDARGS
-int plp_snprintf (char *str,size_t count,const char *fmt,...)
-#else
-int plp_snprintf (va_alist) va_dcl
-#endif
-{
-#ifndef HAVE_STDARGS
-    char *str;
-       size_t count;
-    char *fmt;
-#endif
-       int n = 0;
-    VA_LOCAL_DECL
-
-    VA_START (fmt);
-    VA_SHIFT (str, char *);
-    VA_SHIFT (count, size_t );
-    VA_SHIFT (fmt, char *);
-    n = plp_vsnprintf ( str, count, fmt, ap);
-    VA_END;
-       return( n );
-}
-
-
-/* VARARGS3 */
-#ifdef HAVE_STDARGS
-int plp_unsafe_snprintf (char *str,size_t count,const char *fmt,...)
-#else
-int plp_unsafe_snprintf (va_alist) va_dcl
-#endif
-{
-#ifndef HAVE_STDARGS
-    char *str;
-       size_t count;
-    char *fmt;
-#endif
-       int n = 0;
-    VA_LOCAL_DECL
-
-    VA_START (fmt);
-    VA_SHIFT (str, char *);
-    VA_SHIFT (count, size_t );
-    VA_SHIFT (fmt, char *);
-    n = plp_unsafe_vsnprintf ( str, count, fmt, ap);
-    VA_END;
-       return( n );
-}
- static void dopr( int visible_control, char **buffer, int *left, const char *format, va_list args )
-{
-       int ch;
-       union value value;
-       int longflag = 0;
-       int quadflag = 0;
-       char *strvalue;
-       int ljust;
-       int len;
-       int zpad;
-       int precision;
-       int set_precision;
-       double dval;
-       int err = errno;
-       int base = 0;
-       int signed_val = 0;
-
-       while( (ch = *format++) ){
-               switch( ch ){
-               case '%':
-                       longflag = quadflag =
-                       ljust = len = zpad = base = signed_val = 0;
-                       precision = -1; set_precision = 0;
-               nextch: 
-                       ch = *format++;
-                       switch( ch ){
-                       case 0:
-                               dostr( buffer, left, "**end of format**" );
-                               return;
-                       case '-': ljust = 1; goto nextch;
-                       case '.': set_precision = 1; precision = 0; goto nextch;
-                       case '*': len = va_arg( args, int ); goto nextch;
-                       case '0': /* set zero padding if len not set */
-                               if(len==0 && set_precision == 0 ) zpad = '0';
-                       case '1': case '2': case '3':
-                       case '4': case '5': case '6':
-                       case '7': case '8': case '9':
-                               if( set_precision ){
-                                       precision = precision*10 + ch - '0';
-                               } else {
-                                       len = len*10 + ch - '0';
-                               }
-                               goto nextch;
-                       case 'l': ++longflag; goto nextch;
-                       case 'q':
-#if !defined( HAVE_QUAD_T )
-                                       dostr( buffer, left, "*no quad_t support *");
-                                       return;
-#endif
-                                       quadflag = 1;
-                                       goto nextch;
-                       case 'u': case 'U':
-                               if( base == 0 ){ base = 10; signed_val = 0; }
-                       case 'o': case 'O':
-                               if( base == 0 ){ base = 8; signed_val = 0; }
-                       case 'd': case 'D':
-                               if( base == 0 ){ base = 10; signed_val = 1; }
-                       case 'x':
-                               if( base == 0 ){ base = 16; signed_val = 0; }
-                       case 'X':
-                               if( base == 0 ){ base = -16; signed_val = 0; }
-#if defined( HAVE_QUAD_T )
-                               if( quadflag ){
-                                       value.qvalue = va_arg( args, quad_t );
-                                       fmtquad( buffer, left,  &value,base,signed_val, ljust, len, zpad, precision );
-                                       break;
-                               } else
-#endif
-                               if( longflag > 1 ){
-#if defined(HAVE_LONG_LONG)
-                                       if( signed_val ){
-                                       value.value = va_arg( args, long long );
-                                       } else {
-                                       value.value = va_arg( args, unsigned long long );
-                                       }
-#else
-                                       if( signed_val ){
-                                       value.value = va_arg( args, long );
-                                       } else {
-                                       value.value = va_arg( args, unsigned long );
-                                       }
-#endif
-                               } else if( longflag ){
-                                       if( signed_val ){
-                                               value.value = va_arg( args, long );
-                                       } else {
-                                               value.value = va_arg( args, unsigned long );
-                                       }
-                               } else {
-                                       if( signed_val ){
-                                               value.value = va_arg( args, int );
-                                       } else {
-                                               value.value = va_arg( args, unsigned int );
-                                       }
-                               }
-                               fmtnum( buffer, left,  &value,base,signed_val, ljust, len, zpad, precision ); break;
-                       case 's':
-                               strvalue = va_arg( args, char *);
-                               fmtstr( visible_control, buffer, left, strvalue,ljust,len, zpad, precision );
-                               break;
-                       case 'c':
-                               ch = va_arg( args, int );
-                               { char b[2];
-                                       b[0] = ch;
-                                       b[1] = 0;
-                                       fmtstr( 0, buffer, left, b,ljust,len, zpad, precision );
-                               }
-                               break;
-                       case 'f': case 'g': case 'e':
-                               dval = va_arg( args, double );
-                               fmtdouble( buffer, left, ch, dval,ljust,len, zpad, precision ); break;
-                       case 'm':
-                               { char shortbuffer[32];
-                               fmtstr( visible_control, buffer, left,
-                                       plp_Errormsg(err, shortbuffer),ljust,len, zpad, precision );
-                               }
-                               break;
-                       case '%': dopr_outch( buffer, left, ch ); continue;
-                       default:
-                               dostr(  buffer, left, "???????" );
-                       }
-                       longflag = 0;
-                       break;
-               default:
-                       dopr_outch( buffer, left, ch );
-                       break;
-               }
-       }
-}
-
-/*
- * Format '%[-]len[.precision]s'
- * -   = left justify (ljust)
- * len = minimum length
- * precision = numbers of chars in string to use
- */
- static void
-fmtstr( int visible_control, char **buffer, int *left,
-        char *value, int ljust, int len, int zpad, int precision )
-{
-       int padlen, strlenv, i, c;      /* amount to pad */
-
-       if( value == 0 ){
-               value = "<NULL>";
-       }
-       /* cheap strlen so you do not have library call */
-       for( strlenv = i = 0; (c=CVAL(value+i)); ++i ){
-               if( visible_control && iscntrl( c ) && c != '\t' && c != '\n' ){
-                       ++strlenv;
-               }
-               ++strlenv;
-       }
-       if( precision > 0 && strlenv > precision ){
-               strlenv = precision;
-       }
-       padlen = len - strlenv;
-       if( padlen < 0 ) padlen = 0;
-       if( ljust ) padlen = -padlen;
-       while( padlen > 0 ) {
-               dopr_outch( buffer, left, ' ' );
-               --padlen;
-       }
-       /* output characters */
-       for( i = 0; i < strlenv && (c = CVAL(value+i)); ++i ){
-               if( visible_control && iscntrl( c ) && c != '\t' && c != '\n' ){
-                       dopr_outch(buffer, left, '^');
-                       c = ('@' | (c & 0x1F));
-               }
-               dopr_outch(buffer, left, c);
-       }
-       while( padlen < 0 ) {
-               dopr_outch( buffer, left, ' ' );
-               ++padlen;
-       }
-}
-
- static void
-fmtnum( char **buffer, int *left,
-       union value *value, int base, int dosign, int ljust,
-       int len, int zpad, int precision )
-{
-       int signvalue = 0;
-#if defined(HAVE_LONG_LONG)
-       unsigned long long uvalue;
-#else
-       unsigned long uvalue;
-#endif
-       char convert[sizeof( union value) * 8 + 16];
-       int place = 0;
-       int padlen = 0; /* amount to pad */
-       int caps = 0;
-
-       /* fprintf(stderr,"value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
-               value, base, dosign, ljust, len, zpad );/ **/
-       uvalue = value->value;
-       if( dosign ){
-               if( value->value < 0 ) {
-                       signvalue = '-';
-                       uvalue = -value->value; 
-               }
-       }
-       if( base < 0 ){
-               caps = 1;
-               base = -base;
-       }
-       do{
-               convert[place++] =
-                       (caps? "0123456789ABCDEF":"0123456789abcdef")
-                        [uvalue % (unsigned)base  ];
-               uvalue = (uvalue / (unsigned)base );
-       }while(uvalue);
-       convert[place] = 0;
-       padlen = len - place;
-       if( padlen < 0 ) padlen = 0;
-       if( ljust ) padlen = -padlen;
-       /* fprintf( stderr, "str '%s', place %d, sign %c, padlen %d\n",
-               convert,place,signvalue,padlen); / **/
-       if( zpad && padlen > 0 ){
-               if( signvalue ){
-                       dopr_outch( buffer, left, signvalue );
-                       --padlen;
-                       signvalue = 0;
-               }
-               while( padlen > 0 ){
-                       dopr_outch( buffer, left, zpad );
-                       --padlen;
-               }
-       }
-       while( padlen > 0 ) {
-               dopr_outch( buffer, left, ' ' );
-               --padlen;
-       }
-       if( signvalue ) dopr_outch( buffer, left, signvalue );
-       while( place > 0 ) dopr_outch( buffer, left, convert[--place] );
-       while( padlen < 0 ){
-               dopr_outch( buffer, left, ' ' );
-               ++padlen;
-       }
-}
-
-#if defined(HAVE_QUAD_T)
-
- static void
-fmtquad( char **buffer, int *left,
-       union value *value, int base, int dosign, int ljust,
-       int len, int zpad, int precision )
-{
-       int signvalue = 0;
-       int place = 0;
-       int padlen = 0; /* amount to pad */
-       int caps = 0;
-       int i, c;
-       union {
-               quad_t qvalue;
-               unsigned char qconvert[sizeof(quad_t)];
-       } vvalue;
-       char convert[2*sizeof(quad_t)+1];
-
-       /* fprintf(stderr,"value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
-               value, base, dosign, ljust, len, zpad );/ **/
-       vvalue.qvalue = value->qvalue;
-
-       if( base < 0 ){
-               caps = 1;
-       }
-
-       for( i = 0; i < sizeof(quad_t); ++i ){
-               c = vvalue.qconvert[i];
-               convert[2*i] = 
-                       (caps? "0123456789ABCDEF":"0123456789abcdef")[ (c >> 4) & 0xF];
-               convert[2*i+1] = 
-                       (caps? "0123456789ABCDEF":"0123456789abcdef")[ c  & 0xF];
-       }
-       convert[2*i] = 0;
-
-       place = strlen(convert);
-       padlen = len - place;
-       if( padlen < 0 ) padlen = 0;
-       if( ljust ) padlen = -padlen;
-       /* fprintf( stderr, "str '%s', place %d, sign %c, padlen %d\n",
-               convert,place,signvalue,padlen); / **/
-       if( zpad && padlen > 0 ){
-               if( signvalue ){
-                       dopr_outch( buffer, left, signvalue );
-                       --padlen;
-                       signvalue = 0;
-               }
-               while( padlen > 0 ){
-                       dopr_outch( buffer, left, zpad );
-                       --padlen;
-               }
-       }
-       while( padlen > 0 ) {
-               dopr_outch( buffer, left, ' ' );
-               --padlen;
-       }
-       if( signvalue ) dopr_outch( buffer, left, signvalue );
-       while( place > 0 ) dopr_outch( buffer, left, convert[--place] );
-       while( padlen < 0 ){
-               dopr_outch( buffer, left, ' ' );
-               ++padlen;
-       }
-}
-
-#endif
-
- static void mystrcat(char *dest, char *src )
-{
-       if( dest && src ){
-               dest += strlen(dest);
-               strcpy(dest,src);
-       }
-}
-
- static void
-fmtdouble( char **buffer, int *left,
-       int fmt, double value, int ljust, int len, int zpad, int precision )
-{
-       char convert[sizeof( union value) * 8 + 16];
-       char formatstr[128];
-
-       /* fprintf(stderr,"len %d, precision %d\n", len, precision ); */
-       if( len > (sizeof(convert) - 20) ){
-               len = sizeof(convert) - 20;
-       }
-       if( precision >= 0 && precision > sizeof(convert) - 20 ){
-               precision = sizeof(convert) - 20;
-       }
-       if( precision >= 0 && precision > len ) precision = len;
-       strcpy( formatstr, "%" );
-       if( ljust ) mystrcat(formatstr, "-" );
-       if( zpad ) mystrcat(formatstr, "0" );
-       if( len ){
-               sprintf( formatstr+strlen(formatstr), "%d", len );
-       }
-       if( precision >= 0 ){
-               sprintf( formatstr+strlen(formatstr), ".%d", precision );
-       }
-       sprintf( formatstr+strlen(formatstr), "%c", fmt );
-       /* this is easier than trying to do the portable dtostr */
-       /* fprintf(stderr,"format string '%s'\n", formatstr); */
-       sprintf( convert, formatstr, value );
-       dostr( buffer, left, convert );
-}
-
- static void dostr( char **buffer, int *left, char *str  )
-{
-       if(str)while(*str) dopr_outch( buffer, left, *str++ );
-}
-
- static void dopr_outch( char **buffer, int *left, int c )
-{
-       if( *left > 0 ){
-               *(*buffer)++ = c;
-       }
-       *left -= 1;
-}
-
-
-/****************************************************************************
- * static char *plp_errormsg( int err )
- *  returns a printable form of the
- *  errormessage corresponding to the valie of err.
- *  This is the poor man's version of sperror(), not available on all systems
- *  Patrick Powell Tue Apr 11 08:05:05 PDT 1995
- ****************************************************************************/
-/****************************************************************************/
-
-#if !defined(HAVE_STRERROR)
-# undef  num_errors
-# if defined(HAVE_SYS_ERRLIST)
-#  if !defined(HAVE_DECL_SYS_ERRLIST)
-     extern const char *const sys_errlist[];
-#  endif
-#  if defined(HAVE_SYS_NERR)
-#   if !defined(HAVE_DECL_SYS_NERR)
-      extern int sys_nerr;
-#   endif
-#   define num_errors    (sys_nerr)
-#  endif
-# endif
-# if !defined(num_errors)
-#   define num_errors   (-1)            /* always use "errno=%d" */
-# endif
-#endif
-
- static char * plp_Errormsg ( int err, char *buffer /* int maxlen = 32 */)
-{
-    char *cp;
-
-#if defined(HAVE_STRERROR)
-       cp = (void *)strerror(err);
-#else
-# if defined(HAVE_SYS_ERRLIST)
-    if (err >= 0 && err < num_errors) {
-               cp = (void *)sys_errlist[err];
-    } else
-# endif
-       {
-               (void) sprintf (buffer, "errno=%d", err);
-               cp = buffer;
-    }
-#endif
-    return (cp);
-}
-
-#if defined(TEST)
-#include <stdio.h>
-int main( void )
-{
-       char buffer[128];
-       char *t;
-       char *test1 = "01234";
-       int n;
-       errno = 1;
-       buffer[0] = 0;
-       n = plp_snprintf( buffer, 0, (t="test")); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t="errno '%s'")); printf( "[%d] %s = '%s'\n", n, t, buffer, strerror(errno) );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%12s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%-12s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%12.2s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%-12.2s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%g"), 1.2345 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%12g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%12.1g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%12.2g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%12.3g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%0*d"), 6, 1 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-#if defined(HAVE_LONG_LONG)
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%llx"), 1, 2, 3, 4 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%llx"), (long long)1, (long long)2 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%qx"), 1, 2, 3, 4 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%qx"), (quad_t)1, (quad_t)2 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-#endif
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "0%x, 0%x"), (char *)(0x01234567), (char *)0, 0, 0, 0); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "0%x, 0%x"), (char *)(0x01234567), (char *)0x89ABCDEF, 0, 0, 0); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "0%x, 0%x"), t, 0, 0, 0, 0); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%f"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%f"), 1.2345 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%12f"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%12.2f"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%.0f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%0.0f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%1.0f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%1.5f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       n = plp_snprintf( buffer, sizeof(buffer), (t = "%5.5f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer );
-       return(0);
-}
-#endif
-
-#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
-
-#ifndef HAVE_VSNPRINTF
-int vsnprintf(char *str, size_t count, const char *fmt, va_list args)
-{
-    int n;
-    
-    n = plp_vsnprintf(str, count, fmt, args);
-    
-    return(n);
-}
-#endif /* ! HAVE_VSNPRINTF */
-
-#ifndef HAVE_SNPRINTF
-#ifdef HAVE_STDARGS
-int snprintf (char *str,size_t count,const char *fmt,...)
-#else
-int snprintf (va_alist) va_dcl
-#endif
-{
-#ifndef HAVE_STDARGS
-    char *str;
-       size_t count;
-    char *fmt;
-#endif
-       int n = 0;
-    VA_LOCAL_DECL
-
-    VA_START (fmt);
-    VA_SHIFT (str, char *);
-    VA_SHIFT (count, size_t );
-    VA_SHIFT (fmt, char *);
-    n = plp_vsnprintf ( str, count, fmt, ap);
-    VA_END;
-       return( n );
-}
-#endif /* ! HAVE_VNSPRINTF */
diff --git a/libatalk/compat/strcasecmp.c b/libatalk/compat/strcasecmp.c
deleted file mode 100644 (file)
index bc8cb57..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * $Id: strcasecmp.c,v 1.4 2003-02-17 01:51:08 srittau Exp $
- *
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that: (1) source distributions retain this entire copyright
- * notice and comment, and (2) distributions including binaries display
- * the following acknowledgement:  ``This product includes software
- * developed by the University of California, Berkeley and its contributors''
- * in the documentation or other materials provided with the distribution
- * and in all advertising materials mentioning features or use of this
- * software. Neither the name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-# if defined( ibm032 )
-
-#include <sys/types.h>
-#include <string.h>
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static const char sccsid[] = "@(#)strcasecmp.c 5.9 (Berkeley) 6/1/90";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * This array is designed for mapping upper and lower case letter
- * together for a case independent comparison.  The mappings are
- * based upon ascii character sequences.
- */
-static u_char charmap[] = {
-       '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
-       '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
-       '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
-       '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
-       '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
-       '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
-       '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
-       '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
-       '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
-       '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
-       '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
-       '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
-       '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
-       '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
-       '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
-       '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
-       '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
-       '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
-       '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
-       '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
-       '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
-       '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
-       '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
-       '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
-       '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
-       '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
-       '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
-       '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
-       '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
-       '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
-       '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
-       '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
-};
-
-int
-strcasecmp(s1, s2)
-       char *s1, *s2;
-{
-       register u_char *cm = charmap,
-                       *us1 = (u_char *)s1,
-                       *us2 = (u_char *)s2;
-
-       while (cm[*us1] == cm[*us2++])
-               if (*us1++ == '\0')
-                       return (0);
-       return (cm[*us1] - cm[*--us2]);
-}
-
-int
-strncasecmp(s1, s2, n)
-       char *s1, *s2;
-       register size_t n;
-{
-       if (n != 0) {
-               register u_char *cm = charmap,
-                               *us1 = (u_char *)s1,
-                               *us2 = (u_char *)s2;
-
-               do {
-                       if (cm[*us1] != cm[*us2++])
-                               return (cm[*us1] - cm[*--us2]);
-                       if (*us1++ == '\0')
-                               break;
-               } while (--n != 0);
-       }
-       return (0);
-}
-
-# endif /* ibm032 */
diff --git a/libatalk/compat/strdup.c b/libatalk/compat/strdup.c
deleted file mode 100644 (file)
index 9537a85..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * $Id: strdup.c,v 1.4 2003-02-17 01:51:08 srittau Exp $
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef ultrix
-char *strdup(const char *string)
-{
-  char *new;
-  
-  if (new = (char *) malloc(strlen(string) + 1))
-    strcpy(new, string);
-
-  return new;
-}
-#endif /* ultrix */
diff --git a/libatalk/compat/strlcpy.c b/libatalk/compat/strlcpy.c
new file mode 100644 (file)
index 0000000..314b039
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+   Copy from samba lib/replace.c
+
+   Unix SMB/CIFS implementation.
+   replacement routines for broken systems
+   Copyright (C) Andrew Tridgell 1992-1998
+   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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   strlcpy strlcat functions.
+*/
+                          
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <atalk/util.h>
+#include <string.h>
+
+#ifndef HAVE_STRLCPY
+/* like strncpy but does not 0 fill the buffer and always null
+   terminates. bufsize is the size of the destination buffer */
+ size_t strlcpy(char *d, const char *s, size_t bufsize)
+{
+        size_t len = strlen(s);
+        size_t ret = len;
+
+        if (bufsize <= 0) 
+               return 0;
+
+        if (len >= bufsize) 
+               len = bufsize-1;
+
+        memcpy(d, s, len);
+        d[len] = 0;
+        return ret;
+}
+#endif
+#ifndef HAVE_STRLCAT
+/* like strncat but does not 0 fill the buffer and always null
+   terminates. bufsize is the length of the buffer, which should
+   be one more than the maximum resulting string length */
+ size_t strlcat(char *d, const char *s, size_t bufsize)
+{
+        size_t len1 = strlen(d);
+        size_t len2 = strlen(s);
+        size_t ret = len1 + len2;
+
+       if (len1 >= bufsize) {
+               return 0;
+       } 
+        if (len1+len2 >= bufsize) {
+                len2 = bufsize - (len1+1);
+        }
+        if (len2 > 0) {
+                memcpy(d+len1, s, len2);
+                d[len1+len2] = 0;
+        }
+        return ret;
+}
+#endif
diff --git a/libatalk/compat/strstr.c b/libatalk/compat/strstr.c
deleted file mode 100644 (file)
index ae555b4..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * $Id: strstr.c,v 1.4 2003-02-17 01:51:08 srittau Exp $
- *
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS 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 REGENTS OR 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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strstr.c   5.2 (Berkeley) 1/26/91";
-#endif /* LIBC_SCCS and not lint */
-
-# if defined(ibm032) || (defined(sun) && defined(i386))
-#ifdef sun
-#define const
-#endif /* sun */
-
-#include <sys/types.h>
-#include <string.h>
-
-/*
- * Find the first occurrence of find in s.
- */
-char *
-strstr(s, find)
-       register const char *s, *find;
-{
-       register char c, sc;
-       register size_t len;
-
-       if ((c = *find++) != 0) {
-               len = strlen(find);
-               do {
-                       do {
-                               if ((sc = *s++) == 0)
-                                       return (0);
-                       } while (sc != c);
-               } while (strncmp(s, find, len) != 0);
-               s--;
-       }
-       return ((char *)s);
-}
-# endif /* ibm03 sun i386 */
diff --git a/libatalk/talloc/Makefile.am b/libatalk/talloc/Makefile.am
new file mode 100644 (file)
index 0000000..0b011ed
--- /dev/null
@@ -0,0 +1,7 @@
+# Makefile.am for libatalk/talloc/
+
+noinst_LTLIBRARIES = libtalloc.la
+
+AM_CFLAGS = 
+
+libtalloc_la_SOURCES = talloc.c
diff --git a/libatalk/talloc/talloc.c b/libatalk/talloc/talloc.c
new file mode 100644 (file)
index 0000000..f56ec43
--- /dev/null
@@ -0,0 +1,1990 @@
+/* 
+   Samba Unix SMB/CIFS implementation.
+
+   Samba trivial allocation library - new interface
+
+   NOTE: Please read talloc_guide.txt for full documentation
+
+   Copyright (C) Andrew Tridgell 2004
+   Copyright (C) Stefan Metzmacher 2006
+   
+     ** NOTE! The following LGPL license applies to the talloc
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+   
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+  inspired by http://swapped.cc/halloc/
+*/
+
+#include <string.h>
+#include <stdbool.h>
+
+#include <atalk/compat.h>
+#include <atalk/util.h>
+#include <atalk/talloc.h>
+
+#ifdef TALLOC_BUILD_VERSION_MAJOR
+#if (TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR)
+#error "TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR"
+#endif
+#endif
+
+#ifdef TALLOC_BUILD_VERSION_MINOR
+#if (TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR)
+#error "TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR"
+#endif
+#endif
+
+/* use this to force every realloc to change the pointer, to stress test
+   code that might not cope */
+#define ALWAYS_REALLOC 0
+
+
+#define MAX_TALLOC_SIZE 0x10000000
+#define TALLOC_MAGIC_BASE 0xe814ec70
+#define TALLOC_MAGIC ( \
+       TALLOC_MAGIC_BASE + \
+       (TALLOC_VERSION_MAJOR << 12) + \
+       (TALLOC_VERSION_MINOR << 4) \
+)
+
+#define TALLOC_FLAG_FREE 0x01
+#define TALLOC_FLAG_LOOP 0x02
+#define TALLOC_FLAG_POOL 0x04          /* This is a talloc pool */
+#define TALLOC_FLAG_POOLMEM 0x08       /* This is allocated in a pool */
+#define TALLOC_MAGIC_REFERENCE ((const char *)1)
+
+/* by default we abort when given a bad pointer (such as when talloc_free() is called 
+   on a pointer that came from malloc() */
+#ifndef TALLOC_ABORT
+#define TALLOC_ABORT(reason) abort()
+#endif
+
+#ifndef discard_const_p
+#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
+# define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
+#else
+# define discard_const_p(type, ptr) ((type *)(ptr))
+#endif
+#endif
+
+/* these macros gain us a few percent of speed on gcc */
+#if (__GNUC__ >= 3)
+/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
+   as its first argument */
+#ifndef likely
+#define likely(x)   __builtin_expect(!!(x), 1)
+#endif
+#ifndef unlikely
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#endif
+#else
+#ifndef likely
+#define likely(x) (x)
+#endif
+#ifndef unlikely
+#define unlikely(x) (x)
+#endif
+#endif
+
+/* this null_context is only used if talloc_enable_leak_report() or
+   talloc_enable_leak_report_full() is called, otherwise it remains
+   NULL
+*/
+static void *null_context;
+static void *autofree_context;
+
+struct talloc_reference_handle {
+       struct talloc_reference_handle *next, *prev;
+       void *ptr;
+       const char *location;
+};
+
+typedef int (*talloc_destructor_t)(void *);
+
+struct talloc_chunk {
+       struct talloc_chunk *next, *prev;
+       struct talloc_chunk *parent, *child;
+       struct talloc_reference_handle *refs;
+       talloc_destructor_t destructor;
+       const char *name;
+       size_t size;
+       unsigned flags;
+
+       /*
+        * "pool" has dual use:
+        *
+        * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool"
+        * marks the end of the currently allocated area.
+        *
+        * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
+        * is a pointer to the struct talloc_chunk of the pool that it was
+        * allocated from. This way children can quickly find the pool to chew
+        * from.
+        */
+       void *pool;
+};
+
+/* 16 byte alignment seems to keep everyone happy */
+#define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
+#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
+
+int talloc_version_major(void)
+{
+       return TALLOC_VERSION_MAJOR;
+}
+
+int talloc_version_minor(void)
+{
+       return TALLOC_VERSION_MINOR;
+}
+
+static void (*talloc_log_fn)(const char *message);
+
+void talloc_set_log_fn(void (*log_fn)(const char *message))
+{
+       talloc_log_fn = log_fn;
+}
+
+static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
+static void talloc_log(const char *fmt, ...)
+{
+       va_list ap;
+       char *message;
+
+       if (!talloc_log_fn) {
+               return;
+       }
+
+       va_start(ap, fmt);
+       message = talloc_vasprintf(NULL, fmt, ap);
+       va_end(ap);
+
+       talloc_log_fn(message);
+       talloc_free(message);
+}
+
+static void talloc_log_stderr(const char *message)
+{
+       fprintf(stderr, "%s", message);
+}
+
+void talloc_set_log_stderr(void)
+{
+       talloc_set_log_fn(talloc_log_stderr);
+}
+
+static void (*talloc_abort_fn)(const char *reason);
+
+void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
+{
+       talloc_abort_fn = abort_fn;
+}
+
+static void talloc_abort(const char *reason)
+{
+       talloc_log("%s\n", reason);
+
+       if (!talloc_abort_fn) {
+               TALLOC_ABORT(reason);
+       }
+
+       talloc_abort_fn(reason);
+}
+
+static void talloc_abort_magic(unsigned magic)
+{
+       unsigned striped = magic - TALLOC_MAGIC_BASE;
+       unsigned major = (striped & 0xFFFFF000) >> 12;
+       unsigned minor = (striped & 0x00000FF0) >> 4;
+       talloc_log("Bad talloc magic[0x%08X/%u/%u] expected[0x%08X/%u/%u]\n",
+                  magic, major, minor,
+                  TALLOC_MAGIC, TALLOC_VERSION_MAJOR, TALLOC_VERSION_MINOR);
+       talloc_abort("Bad talloc magic value - wrong talloc version used/mixed");
+}
+
+static void talloc_abort_double_free(void)
+{
+       talloc_abort("Bad talloc magic value - double free");
+}
+
+static void talloc_abort_unknown_value(void)
+{
+       talloc_abort("Bad talloc magic value - unknown value");
+}
+
+/* panic if we get a bad magic value */
+static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
+{
+       const char *pp = (const char *)ptr;
+       struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
+       if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) { 
+               if ((tc->flags & (~0xFFF)) == TALLOC_MAGIC_BASE) {
+                       talloc_abort_magic(tc->flags & (~0xF));
+                       return NULL;
+               }
+
+               if (tc->flags & TALLOC_FLAG_FREE) {
+                       talloc_log("talloc: double free error - first free may be at %s\n", tc->name);
+                       talloc_abort_double_free();
+                       return NULL;
+               } else {
+                       talloc_abort_unknown_value();
+                       return NULL;
+               }
+       }
+       return tc;
+}
+
+/* hook into the front of the list */
+#define _TLIST_ADD(list, p) \
+do { \
+        if (!(list)) { \
+               (list) = (p); \
+               (p)->next = (p)->prev = NULL; \
+       } else { \
+               (list)->prev = (p); \
+               (p)->next = (list); \
+               (p)->prev = NULL; \
+               (list) = (p); \
+       }\
+} while (0)
+
+/* remove an element from a list - element doesn't have to be in list. */
+#define _TLIST_REMOVE(list, p) \
+do { \
+       if ((p) == (list)) { \
+               (list) = (p)->next; \
+               if (list) (list)->prev = NULL; \
+       } else { \
+               if ((p)->prev) (p)->prev->next = (p)->next; \
+               if ((p)->next) (p)->next->prev = (p)->prev; \
+       } \
+       if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
+} while (0)
+
+
+/*
+  return the parent chunk of a pointer
+*/
+static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
+{
+       struct talloc_chunk *tc;
+
+       if (unlikely(ptr == NULL)) {
+               return NULL;
+       }
+
+       tc = talloc_chunk_from_ptr(ptr);
+       while (tc->prev) tc=tc->prev;
+
+       return tc->parent;
+}
+
+void *talloc_parent(const void *ptr)
+{
+       struct talloc_chunk *tc = talloc_parent_chunk(ptr);
+       return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
+}
+
+/*
+  find parents name
+*/
+const char *talloc_parent_name(const void *ptr)
+{
+       struct talloc_chunk *tc = talloc_parent_chunk(ptr);
+       return tc? tc->name : NULL;
+}
+
+/*
+  A pool carries an in-pool object count count in the first 16 bytes.
+  bytes. This is done to support talloc_steal() to a parent outside of the
+  pool. The count includes the pool itself, so a talloc_free() on a pool will
+  only destroy the pool if the count has dropped to zero. A talloc_free() of a
+  pool member will reduce the count, and eventually also call free(3) on the
+  pool memory.
+
+  The object count is not put into "struct talloc_chunk" because it is only
+  relevant for talloc pools and the alignment to 16 bytes would increase the
+  memory footprint of each talloc chunk by those 16 bytes.
+*/
+
+#define TALLOC_POOL_HDR_SIZE 16
+
+static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc)
+{
+       return (unsigned int *)((char *)tc + sizeof(struct talloc_chunk));
+}
+
+/*
+  Allocate from a pool
+*/
+
+static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
+                                             size_t size)
+{
+       struct talloc_chunk *pool_ctx = NULL;
+       size_t space_left;
+       struct talloc_chunk *result;
+       size_t chunk_size;
+
+       if (parent == NULL) {
+               return NULL;
+       }
+
+       if (parent->flags & TALLOC_FLAG_POOL) {
+               pool_ctx = parent;
+       }
+       else if (parent->flags & TALLOC_FLAG_POOLMEM) {
+               pool_ctx = (struct talloc_chunk *)parent->pool;
+       }
+
+       if (pool_ctx == NULL) {
+               return NULL;
+       }
+
+       space_left = ((char *)pool_ctx + TC_HDR_SIZE + pool_ctx->size)
+               - ((char *)pool_ctx->pool);
+
+       /*
+        * Align size to 16 bytes
+        */
+       chunk_size = ((size + 15) & ~15);
+
+       if (space_left < chunk_size) {
+               return NULL;
+       }
+
+       result = (struct talloc_chunk *)pool_ctx->pool;
+
+#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
+       VALGRIND_MAKE_MEM_UNDEFINED(result, size);
+#endif
+
+       pool_ctx->pool = (void *)((char *)result + chunk_size);
+
+       result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
+       result->pool = pool_ctx;
+
+       *talloc_pool_objectcount(pool_ctx) += 1;
+
+       return result;
+}
+
+/* 
+   Allocate a bit of memory as a child of an existing pointer
+*/
+static inline void *__talloc(const void *context, size_t size)
+{
+       struct talloc_chunk *tc = NULL;
+
+       if (unlikely(context == NULL)) {
+               context = null_context;
+       }
+
+       if (unlikely(size >= MAX_TALLOC_SIZE)) {
+               return NULL;
+       }
+
+       if (context != NULL) {
+               tc = talloc_alloc_pool(talloc_chunk_from_ptr(context),
+                                      TC_HDR_SIZE+size);
+       }
+
+       if (tc == NULL) {
+               tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
+               if (unlikely(tc == NULL)) return NULL;
+               tc->flags = TALLOC_MAGIC;
+               tc->pool  = NULL;
+       }
+
+       tc->size = size;
+       tc->destructor = NULL;
+       tc->child = NULL;
+       tc->name = NULL;
+       tc->refs = NULL;
+
+       if (likely(context)) {
+               struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
+
+               if (parent->child) {
+                       parent->child->parent = NULL;
+                       tc->next = parent->child;
+                       tc->next->prev = tc;
+               } else {
+                       tc->next = NULL;
+               }
+               tc->parent = parent;
+               tc->prev = NULL;
+               parent->child = tc;
+       } else {
+               tc->next = tc->prev = tc->parent = NULL;
+       }
+
+       return TC_PTR_FROM_CHUNK(tc);
+}
+
+/*
+ * Create a talloc pool
+ */
+
+void *talloc_pool(const void *context, size_t size)
+{
+       void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE);
+       struct talloc_chunk *tc;
+
+       if (unlikely(result == NULL)) {
+               return NULL;
+       }
+
+       tc = talloc_chunk_from_ptr(result);
+
+       tc->flags |= TALLOC_FLAG_POOL;
+       tc->pool = (char *)result + TALLOC_POOL_HDR_SIZE;
+
+       *talloc_pool_objectcount(tc) = 1;
+
+#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
+       VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size);
+#endif
+
+       return result;
+}
+
+/*
+  setup a destructor to be called on free of a pointer
+  the destructor should return 0 on success, or -1 on failure.
+  if the destructor fails then the free is failed, and the memory can
+  be continued to be used
+*/
+void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
+{
+       struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
+       tc->destructor = destructor;
+}
+
+/*
+  increase the reference count on a piece of memory. 
+*/
+int talloc_increase_ref_count(const void *ptr)
+{
+       if (unlikely(!talloc_reference(null_context, ptr))) {
+               return -1;
+       }
+       return 0;
+}
+
+/*
+  helper for talloc_reference()
+
+  this is referenced by a function pointer and should not be inline
+*/
+static int talloc_reference_destructor(struct talloc_reference_handle *handle)
+{
+       struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
+       _TLIST_REMOVE(ptr_tc->refs, handle);
+       return 0;
+}
+
+/*
+   more efficient way to add a name to a pointer - the name must point to a 
+   true string constant
+*/
+static inline void _talloc_set_name_const(const void *ptr, const char *name)
+{
+       struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
+       tc->name = name;
+}
+
+/*
+  internal talloc_named_const()
+*/
+static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
+{
+       void *ptr;
+
+       ptr = __talloc(context, size);
+       if (unlikely(ptr == NULL)) {
+               return NULL;
+       }
+
+       _talloc_set_name_const(ptr, name);
+
+       return ptr;
+}
+
+/*
+  make a secondary reference to a pointer, hanging off the given context.
+  the pointer remains valid until both the original caller and this given
+  context are freed.
+  
+  the major use for this is when two different structures need to reference the 
+  same underlying data, and you want to be able to free the two instances separately,
+  and in either order
+*/
+void *_talloc_reference_loc(const void *context, const void *ptr, const char *location)
+{
+       struct talloc_chunk *tc;
+       struct talloc_reference_handle *handle;
+       if (unlikely(ptr == NULL)) return NULL;
+
+       tc = talloc_chunk_from_ptr(ptr);
+       handle = (struct talloc_reference_handle *)_talloc_named_const(context,
+                                                  sizeof(struct talloc_reference_handle),
+                                                  TALLOC_MAGIC_REFERENCE);
+       if (unlikely(handle == NULL)) return NULL;
+
+       /* note that we hang the destructor off the handle, not the
+          main context as that allows the caller to still setup their
+          own destructor on the context if they want to */
+       talloc_set_destructor(handle, talloc_reference_destructor);
+       handle->ptr = discard_const_p(void, ptr);
+       handle->location = location;
+       _TLIST_ADD(tc->refs, handle);
+       return handle->ptr;
+}
+
+static void *_talloc_steal_internal(const void *new_ctx, const void *ptr);
+
+/* 
+   internal talloc_free call
+*/
+static inline int _talloc_free_internal(void *ptr, const char *location)
+{
+       struct talloc_chunk *tc;
+
+       if (unlikely(ptr == NULL)) {
+               return -1;
+       }
+
+       tc = talloc_chunk_from_ptr(ptr);
+
+       if (unlikely(tc->refs)) {
+               int is_child;
+               /* check this is a reference from a child or grantchild
+                * back to it's parent or grantparent
+                *
+                * in that case we need to remove the reference and
+                * call another instance of talloc_free() on the current
+                * pointer.
+                */
+               is_child = talloc_is_parent(tc->refs, ptr);
+               _talloc_free_internal(tc->refs, location);
+               if (is_child) {
+                       return _talloc_free_internal(ptr, location);
+               }
+               return -1;
+       }
+
+       if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
+               /* we have a free loop - stop looping */
+               return 0;
+       }
+
+       if (unlikely(tc->destructor)) {
+               talloc_destructor_t d = tc->destructor;
+               if (d == (talloc_destructor_t)-1) {
+                       return -1;
+               }
+               tc->destructor = (talloc_destructor_t)-1;
+               if (d(ptr) == -1) {
+                       tc->destructor = d;
+                       return -1;
+               }
+               tc->destructor = NULL;
+       }
+
+       if (tc->parent) {
+               _TLIST_REMOVE(tc->parent->child, tc);
+               if (tc->parent->child) {
+                       tc->parent->child->parent = tc->parent;
+               }
+       } else {
+               if (tc->prev) tc->prev->next = tc->next;
+               if (tc->next) tc->next->prev = tc->prev;
+       }
+
+       tc->flags |= TALLOC_FLAG_LOOP;
+
+       while (tc->child) {
+               /* we need to work out who will own an abandoned child
+                  if it cannot be freed. In priority order, the first
+                  choice is owner of any remaining reference to this
+                  pointer, the second choice is our parent, and the
+                  final choice is the null context. */
+               void *child = TC_PTR_FROM_CHUNK(tc->child);
+               const void *new_parent = null_context;
+               if (unlikely(tc->child->refs)) {
+                       struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
+                       if (p) new_parent = TC_PTR_FROM_CHUNK(p);
+               }
+               if (unlikely(_talloc_free_internal(child, location) == -1)) {
+                       if (new_parent == null_context) {
+                               struct talloc_chunk *p = talloc_parent_chunk(ptr);
+                               if (p) new_parent = TC_PTR_FROM_CHUNK(p);
+                       }
+                       _talloc_steal_internal(new_parent, child);
+               }
+       }
+
+       tc->flags |= TALLOC_FLAG_FREE;
+
+       /* we mark the freed memory with where we called the free
+        * from. This means on a double free error we can report where
+        * the first free came from 
+        */      
+       tc->name = location;
+
+       if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) {
+               struct talloc_chunk *pool;
+               unsigned int *pool_object_count;
+
+               pool = (tc->flags & TALLOC_FLAG_POOL)
+                       ? tc : (struct talloc_chunk *)tc->pool;
+
+               pool_object_count = talloc_pool_objectcount(pool);
+
+               if (*pool_object_count == 0) {
+                       talloc_abort("Pool object count zero!");
+                       return 0;
+               }
+
+               *pool_object_count -= 1;
+
+               if (*pool_object_count == 0) {
+                       free(pool);
+               }
+       }
+       else {
+               free(tc);
+       }
+       return 0;
+}
+
+/* 
+   move a lump of memory from one talloc context to another return the
+   ptr on success, or NULL if it could not be transferred.
+   passing NULL as ptr will always return NULL with no side effects.
+*/
+static void *_talloc_steal_internal(const void *new_ctx, const void *ptr)
+{
+       struct talloc_chunk *tc, *new_tc;
+
+       if (unlikely(!ptr)) {
+               return NULL;
+       }
+
+       if (unlikely(new_ctx == NULL)) {
+               new_ctx = null_context;
+       }
+
+       tc = talloc_chunk_from_ptr(ptr);
+
+       if (unlikely(new_ctx == NULL)) {
+               if (tc->parent) {
+                       _TLIST_REMOVE(tc->parent->child, tc);
+                       if (tc->parent->child) {
+                               tc->parent->child->parent = tc->parent;
+                       }
+               } else {
+                       if (tc->prev) tc->prev->next = tc->next;
+                       if (tc->next) tc->next->prev = tc->prev;
+               }
+               
+               tc->parent = tc->next = tc->prev = NULL;
+               return discard_const_p(void, ptr);
+       }
+
+       new_tc = talloc_chunk_from_ptr(new_ctx);
+
+       if (unlikely(tc == new_tc || tc->parent == new_tc)) {
+               return discard_const_p(void, ptr);
+       }
+
+       if (tc->parent) {
+               _TLIST_REMOVE(tc->parent->child, tc);
+               if (tc->parent->child) {
+                       tc->parent->child->parent = tc->parent;
+               }
+       } else {
+               if (tc->prev) tc->prev->next = tc->next;
+               if (tc->next) tc->next->prev = tc->prev;
+       }
+
+       tc->parent = new_tc;
+       if (new_tc->child) new_tc->child->parent = NULL;
+       _TLIST_ADD(new_tc->child, tc);
+
+       return discard_const_p(void, ptr);
+}
+
+/* 
+   move a lump of memory from one talloc context to another return the
+   ptr on success, or NULL if it could not be transferred.
+   passing NULL as ptr will always return NULL with no side effects.
+*/
+void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location)
+{
+       struct talloc_chunk *tc;
+
+       if (unlikely(ptr == NULL)) {
+               return NULL;
+       }
+       
+       tc = talloc_chunk_from_ptr(ptr);
+       
+       if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) {
+               struct talloc_reference_handle *h;
+
+               talloc_log("WARNING: talloc_steal with references at %s\n",
+                          location);
+
+               for (h=tc->refs; h; h=h->next) {
+                       talloc_log("\treference at %s\n",
+                                  h->location);
+               }
+       }
+       
+       return _talloc_steal_internal(new_ctx, ptr);
+}
+
+/* 
+   this is like a talloc_steal(), but you must supply the old
+   parent. This resolves the ambiguity in a talloc_steal() which is
+   called on a context that has more than one parent (via references)
+
+   The old parent can be either a reference or a parent
+*/
+void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr)
+{
+       struct talloc_chunk *tc;
+       struct talloc_reference_handle *h;
+
+       if (unlikely(ptr == NULL)) {
+               return NULL;
+       }
+
+       if (old_parent == talloc_parent(ptr)) {
+               return _talloc_steal_internal(new_parent, ptr);
+       }
+
+       tc = talloc_chunk_from_ptr(ptr);
+       for (h=tc->refs;h;h=h->next) {
+               if (talloc_parent(h) == old_parent) {
+                       if (_talloc_steal_internal(new_parent, h) != h) {
+                               return NULL;
+                       }
+                       return discard_const_p(void, ptr);
+               }
+       }       
+
+       /* it wasn't a parent */
+       return NULL;
+}
+
+/*
+  remove a secondary reference to a pointer. This undo's what
+  talloc_reference() has done. The context and pointer arguments
+  must match those given to a talloc_reference()
+*/
+static inline int talloc_unreference(const void *context, const void *ptr)
+{
+       struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
+       struct talloc_reference_handle *h;
+
+       if (unlikely(context == NULL)) {
+               context = null_context;
+       }
+
+       for (h=tc->refs;h;h=h->next) {
+               struct talloc_chunk *p = talloc_parent_chunk(h);
+               if (p == NULL) {
+                       if (context == NULL) break;
+               } else if (TC_PTR_FROM_CHUNK(p) == context) {
+                       break;
+               }
+       }
+       if (h == NULL) {
+               return -1;
+       }
+
+       return _talloc_free_internal(h, __location__);
+}
+
+/*
+  remove a specific parent context from a pointer. This is a more
+  controlled varient of talloc_free()
+*/
+int talloc_unlink(const void *context, void *ptr)
+{
+       struct talloc_chunk *tc_p, *new_p;
+       void *new_parent;
+
+       if (ptr == NULL) {
+               return -1;
+       }
+
+       if (context == NULL) {
+               context = null_context;
+       }
+
+       if (talloc_unreference(context, ptr) == 0) {
+               return 0;
+       }
+
+       if (context == NULL) {
+               if (talloc_parent_chunk(ptr) != NULL) {
+                       return -1;
+               }
+       } else {
+               if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
+                       return -1;
+               }
+       }
+       
+       tc_p = talloc_chunk_from_ptr(ptr);
+
+       if (tc_p->refs == NULL) {
+               return _talloc_free_internal(ptr, __location__);
+       }
+
+       new_p = talloc_parent_chunk(tc_p->refs);
+       if (new_p) {
+               new_parent = TC_PTR_FROM_CHUNK(new_p);
+       } else {
+               new_parent = NULL;
+       }
+
+       if (talloc_unreference(new_parent, ptr) != 0) {
+               return -1;
+       }
+
+       _talloc_steal_internal(new_parent, ptr);
+
+       return 0;
+}
+
+/*
+  add a name to an existing pointer - va_list version
+*/
+static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
+
+static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
+{
+       struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
+       tc->name = talloc_vasprintf(ptr, fmt, ap);
+       if (likely(tc->name)) {
+               _talloc_set_name_const(tc->name, ".name");
+       }
+       return tc->name;
+}
+
+/*
+  add a name to an existing pointer
+*/
+const char *talloc_set_name(const void *ptr, const char *fmt, ...)
+{
+       const char *name;
+       va_list ap;
+       va_start(ap, fmt);
+       name = talloc_set_name_v(ptr, fmt, ap);
+       va_end(ap);
+       return name;
+}
+
+
+/*
+  create a named talloc pointer. Any talloc pointer can be named, and
+  talloc_named() operates just like talloc() except that it allows you
+  to name the pointer.
+*/
+void *talloc_named(const void *context, size_t size, const char *fmt, ...)
+{
+       va_list ap;
+       void *ptr;
+       const char *name;
+
+       ptr = __talloc(context, size);
+       if (unlikely(ptr == NULL)) return NULL;
+
+       va_start(ap, fmt);
+       name = talloc_set_name_v(ptr, fmt, ap);
+       va_end(ap);
+
+       if (unlikely(name == NULL)) {
+               _talloc_free_internal(ptr, __location__);
+               return NULL;
+       }
+
+       return ptr;
+}
+
+/*
+  return the name of a talloc ptr, or "UNNAMED"
+*/
+const char *talloc_get_name(const void *ptr)
+{
+       struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
+       if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
+               return ".reference";
+       }
+       if (likely(tc->name)) {
+               return tc->name;
+       }
+       return "UNNAMED";
+}
+
+
+/*
+  check if a pointer has the given name. If it does, return the pointer,
+  otherwise return NULL
+*/
+void *talloc_check_name(const void *ptr, const char *name)
+{
+       const char *pname;
+       if (unlikely(ptr == NULL)) return NULL;
+       pname = talloc_get_name(ptr);
+       if (likely(pname == name || strcmp(pname, name) == 0)) {
+               return discard_const_p(void, ptr);
+       }
+       return NULL;
+}
+
+static void talloc_abort_type_missmatch(const char *location,
+                                       const char *name,
+                                       const char *expected)
+{
+       const char *reason;
+
+       reason = talloc_asprintf(NULL,
+                                "%s: Type mismatch: name[%s] expected[%s]",
+                                location,
+                                name?name:"NULL",
+                                expected);
+       if (!reason) {
+               reason = "Type mismatch";
+       }
+
+       talloc_abort(reason);
+}
+
+void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
+{
+       const char *pname;
+
+       if (unlikely(ptr == NULL)) {
+               talloc_abort_type_missmatch(location, NULL, name);
+               return NULL;
+       }
+
+       pname = talloc_get_name(ptr);
+       if (likely(pname == name || strcmp(pname, name) == 0)) {
+               return discard_const_p(void, ptr);
+       }
+
+       talloc_abort_type_missmatch(location, pname, name);
+       return NULL;
+}
+
+/*
+  this is for compatibility with older versions of talloc
+*/
+void *talloc_init(const char *fmt, ...)
+{
+       va_list ap;
+       void *ptr;
+       const char *name;
+
+       /*
+        * samba3 expects talloc_report_depth_cb(NULL, ...)
+        * reports all talloc'ed memory, so we need to enable
+        * null_tracking
+        */
+       talloc_enable_null_tracking();
+
+       ptr = __talloc(NULL, 0);
+       if (unlikely(ptr == NULL)) return NULL;
+
+       va_start(ap, fmt);
+       name = talloc_set_name_v(ptr, fmt, ap);
+       va_end(ap);
+
+       if (unlikely(name == NULL)) {
+               _talloc_free_internal(ptr, __location__);
+               return NULL;
+       }
+
+       return ptr;
+}
+
+/*
+  this is a replacement for the Samba3 talloc_destroy_pool functionality. It
+  should probably not be used in new code. It's in here to keep the talloc
+  code consistent across Samba 3 and 4.
+*/
+void talloc_free_children(void *ptr)
+{
+       struct talloc_chunk *tc;
+
+       if (unlikely(ptr == NULL)) {
+               return;
+       }
+
+       tc = talloc_chunk_from_ptr(ptr);
+
+       while (tc->child) {
+               /* we need to work out who will own an abandoned child
+                  if it cannot be freed. In priority order, the first
+                  choice is owner of any remaining reference to this
+                  pointer, the second choice is our parent, and the
+                  final choice is the null context. */
+               void *child = TC_PTR_FROM_CHUNK(tc->child);
+               const void *new_parent = null_context;
+               if (unlikely(tc->child->refs)) {
+                       struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
+                       if (p) new_parent = TC_PTR_FROM_CHUNK(p);
+               }
+               if (unlikely(talloc_free(child) == -1)) {
+                       if (new_parent == null_context) {
+                               struct talloc_chunk *p = talloc_parent_chunk(ptr);
+                               if (p) new_parent = TC_PTR_FROM_CHUNK(p);
+                       }
+                       _talloc_steal_internal(new_parent, child);
+               }
+       }
+
+       if ((tc->flags & TALLOC_FLAG_POOL)
+           && (*talloc_pool_objectcount(tc) == 1)) {
+               tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE);
+#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
+               VALGRIND_MAKE_MEM_NOACCESS(
+                       tc->pool, tc->size - TALLOC_POOL_HDR_SIZE);
+#endif
+       }
+}
+
+/* 
+   Allocate a bit of memory as a child of an existing pointer
+*/
+void *_talloc(const void *context, size_t size)
+{
+       return __talloc(context, size);
+}
+
+/*
+  externally callable talloc_set_name_const()
+*/
+void talloc_set_name_const(const void *ptr, const char *name)
+{
+       _talloc_set_name_const(ptr, name);
+}
+
+/*
+  create a named talloc pointer. Any talloc pointer can be named, and
+  talloc_named() operates just like talloc() except that it allows you
+  to name the pointer.
+*/
+void *talloc_named_const(const void *context, size_t size, const char *name)
+{
+       return _talloc_named_const(context, size, name);
+}
+
+/* 
+   free a talloc pointer. This also frees all child pointers of this 
+   pointer recursively
+
+   return 0 if the memory is actually freed, otherwise -1. The memory
+   will not be freed if the ref_count is > 1 or the destructor (if
+   any) returns non-zero
+*/
+int _talloc_free(void *ptr, const char *location)
+{
+       struct talloc_chunk *tc;
+
+       if (unlikely(ptr == NULL)) {
+               return -1;
+       }
+       
+       tc = talloc_chunk_from_ptr(ptr);
+       
+       if (unlikely(tc->refs != NULL)) {
+               struct talloc_reference_handle *h;
+
+               talloc_log("ERROR: talloc_free with references at %s\n",
+                          location);
+
+               for (h=tc->refs; h; h=h->next) {
+                       talloc_log("\treference at %s\n",
+                                  h->location);
+               }
+               return -1;
+       }
+       
+       return _talloc_free_internal(ptr, location);
+}
+
+
+
+/*
+  A talloc version of realloc. The context argument is only used if
+  ptr is NULL
+*/
+void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
+{
+       struct talloc_chunk *tc;
+       void *new_ptr;
+       bool malloced = false;
+
+       /* size zero is equivalent to free() */
+       if (unlikely(size == 0)) {
+               talloc_unlink(context, ptr);
+               return NULL;
+       }
+
+       if (unlikely(size >= MAX_TALLOC_SIZE)) {
+               return NULL;
+       }
+
+       /* realloc(NULL) is equivalent to malloc() */
+       if (ptr == NULL) {
+               return _talloc_named_const(context, size, name);
+       }
+
+       tc = talloc_chunk_from_ptr(ptr);
+
+       /* don't allow realloc on referenced pointers */
+       if (unlikely(tc->refs)) {
+               return NULL;
+       }
+
+       /* don't let anybody try to realloc a talloc_pool */
+       if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
+               return NULL;
+       }
+
+       /* don't shrink if we have less than 1k to gain */
+       if ((size < tc->size) && ((tc->size - size) < 1024)) {
+               tc->size = size;
+               return ptr;
+       }
+
+       /* by resetting magic we catch users of the old memory */
+       tc->flags |= TALLOC_FLAG_FREE;
+
+#if ALWAYS_REALLOC
+       new_ptr = malloc(size + TC_HDR_SIZE);
+       if (new_ptr) {
+               memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE);
+               free(tc);
+       }
+#else
+       if (tc->flags & TALLOC_FLAG_POOLMEM) {
+
+               new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
+               *talloc_pool_objectcount((struct talloc_chunk *)
+                                        (tc->pool)) -= 1;
+
+               if (new_ptr == NULL) {
+                       new_ptr = malloc(TC_HDR_SIZE+size);
+                       malloced = true;
+               }
+
+               if (new_ptr) {
+                       memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
+               }
+       }
+       else {
+               new_ptr = realloc(tc, size + TC_HDR_SIZE);
+       }
+#endif
+       if (unlikely(!new_ptr)) {       
+               tc->flags &= ~TALLOC_FLAG_FREE; 
+               return NULL; 
+       }
+
+       tc = (struct talloc_chunk *)new_ptr;
+       tc->flags &= ~TALLOC_FLAG_FREE;
+       if (malloced) {
+               tc->flags &= ~TALLOC_FLAG_POOLMEM;
+       }
+       if (tc->parent) {
+               tc->parent->child = tc;
+       }
+       if (tc->child) {
+               tc->child->parent = tc;
+       }
+
+       if (tc->prev) {
+               tc->prev->next = tc;
+       }
+       if (tc->next) {
+               tc->next->prev = tc;
+       }
+
+       tc->size = size;
+       _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
+
+       return TC_PTR_FROM_CHUNK(tc);
+}
+
+/*
+  a wrapper around talloc_steal() for situations where you are moving a pointer
+  between two structures, and want the old pointer to be set to NULL
+*/
+void *_talloc_move(const void *new_ctx, const void *_pptr)
+{
+       const void **pptr = discard_const_p(const void *,_pptr);
+       void *ret = talloc_steal(new_ctx, discard_const_p(void, *pptr));
+       (*pptr) = NULL;
+       return ret;
+}
+
+/*
+  return the total size of a talloc pool (subtree)
+*/
+size_t talloc_total_size(const void *ptr)
+{
+       size_t total = 0;
+       struct talloc_chunk *c, *tc;
+
+       if (ptr == NULL) {
+               ptr = null_context;
+       }
+       if (ptr == NULL) {
+               return 0;
+       }
+
+       tc = talloc_chunk_from_ptr(ptr);
+
+       if (tc->flags & TALLOC_FLAG_LOOP) {
+               return 0;
+       }
+
+       tc->flags |= TALLOC_FLAG_LOOP;
+
+       if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
+               total = tc->size;
+       }
+       for (c=tc->child;c;c=c->next) {
+               total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
+       }
+
+       tc->flags &= ~TALLOC_FLAG_LOOP;
+
+       return total;
+}
+
+/*
+  return the total number of blocks in a talloc pool (subtree)
+*/
+size_t talloc_total_blocks(const void *ptr)
+{
+       size_t total = 0;
+       struct talloc_chunk *c, *tc;
+
+       if (ptr == NULL) {
+               ptr = null_context;
+       }
+       if (ptr == NULL) {
+               return 0;
+       }
+
+       tc = talloc_chunk_from_ptr(ptr);
+
+       if (tc->flags & TALLOC_FLAG_LOOP) {
+               return 0;
+       }
+
+       tc->flags |= TALLOC_FLAG_LOOP;
+
+       total++;
+       for (c=tc->child;c;c=c->next) {
+               total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
+       }
+
+       tc->flags &= ~TALLOC_FLAG_LOOP;
+
+       return total;
+}
+
+/*
+  return the number of external references to a pointer
+*/
+size_t talloc_reference_count(const void *ptr)
+{
+       struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
+       struct talloc_reference_handle *h;
+       size_t ret = 0;
+
+       for (h=tc->refs;h;h=h->next) {
+               ret++;
+       }
+       return ret;
+}
+
+/*
+  report on memory usage by all children of a pointer, giving a full tree view
+*/
+void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
+                           void (*callback)(const void *ptr,
+                                            int depth, int max_depth,
+                                            int is_ref,
+                                            void *private_data),
+                           void *private_data)
+{
+       struct talloc_chunk *c, *tc;
+
+       if (ptr == NULL) {
+               ptr = null_context;
+       }
+       if (ptr == NULL) return;
+
+       tc = talloc_chunk_from_ptr(ptr);
+
+       if (tc->flags & TALLOC_FLAG_LOOP) {
+               return;
+       }
+
+       callback(ptr, depth, max_depth, 0, private_data);
+
+       if (max_depth >= 0 && depth >= max_depth) {
+               return;
+       }
+
+       tc->flags |= TALLOC_FLAG_LOOP;
+       for (c=tc->child;c;c=c->next) {
+               if (c->name == TALLOC_MAGIC_REFERENCE) {
+                       struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
+                       callback(h->ptr, depth + 1, max_depth, 1, private_data);
+               } else {
+                       talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
+               }
+       }
+       tc->flags &= ~TALLOC_FLAG_LOOP;
+}
+
+static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
+{
+       const char *name = talloc_get_name(ptr);
+       FILE *f = (FILE *)_f;
+
+       if (is_ref) {
+               fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
+               return;
+       }
+
+       if (depth == 0) {
+               fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", 
+                       (max_depth < 0 ? "full " :""), name,
+                       (unsigned long)talloc_total_size(ptr),
+                       (unsigned long)talloc_total_blocks(ptr));
+               return;
+       }
+
+       fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", 
+               depth*4, "",
+               name,
+               (unsigned long)talloc_total_size(ptr),
+               (unsigned long)talloc_total_blocks(ptr),
+               (int)talloc_reference_count(ptr), ptr);
+
+#if 0
+       fprintf(f, "content: ");
+       if (talloc_total_size(ptr)) {
+               int tot = talloc_total_size(ptr);
+               int i;
+
+               for (i = 0; i < tot; i++) {
+                       if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
+                               fprintf(f, "%c", ((char *)ptr)[i]);
+                       } else {
+                               fprintf(f, "~%02x", ((char *)ptr)[i]);
+                       }
+               }
+       }
+       fprintf(f, "\n");
+#endif
+}
+
+/*
+  report on memory usage by all children of a pointer, giving a full tree view
+*/
+void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
+{
+       if (f) {
+               talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
+               fflush(f);
+       }
+}
+
+/*
+  report on memory usage by all children of a pointer, giving a full tree view
+*/
+void talloc_report_full(const void *ptr, FILE *f)
+{
+       talloc_report_depth_file(ptr, 0, -1, f);
+}
+
+/*
+  report on memory usage by all children of a pointer
+*/
+void talloc_report(const void *ptr, FILE *f)
+{
+       talloc_report_depth_file(ptr, 0, 1, f);
+}
+
+/*
+  report on any memory hanging off the null context
+*/
+static void talloc_report_null(void)
+{
+       if (talloc_total_size(null_context) != 0) {
+               talloc_report(null_context, stderr);
+       }
+}
+
+/*
+  report on any memory hanging off the null context
+*/
+static void talloc_report_null_full(void)
+{
+       if (talloc_total_size(null_context) != 0) {
+               talloc_report_full(null_context, stderr);
+       }
+}
+
+/*
+  enable tracking of the NULL context
+*/
+void talloc_enable_null_tracking(void)
+{
+       if (null_context == NULL) {
+               null_context = _talloc_named_const(NULL, 0, "null_context");
+               if (autofree_context != NULL) {
+                       talloc_reparent(NULL, null_context, autofree_context);
+               }
+       }
+}
+
+/*
+  enable tracking of the NULL context, not moving the autofree context
+  into the NULL context. This is needed for the talloc testsuite
+*/
+void talloc_enable_null_tracking_no_autofree(void)
+{
+       if (null_context == NULL) {
+               null_context = _talloc_named_const(NULL, 0, "null_context");
+       }
+}
+
+/*
+  disable tracking of the NULL context
+*/
+void talloc_disable_null_tracking(void)
+{
+       if (null_context != NULL) {
+               /* we have to move any children onto the real NULL
+                  context */
+               struct talloc_chunk *tc, *tc2;
+               tc = talloc_chunk_from_ptr(null_context);
+               for (tc2 = tc->child; tc2; tc2=tc2->next) {
+                       if (tc2->parent == tc) tc2->parent = NULL;
+                       if (tc2->prev == tc) tc2->prev = NULL;
+               }
+               for (tc2 = tc->next; tc2; tc2=tc2->next) {
+                       if (tc2->parent == tc) tc2->parent = NULL;
+                       if (tc2->prev == tc) tc2->prev = NULL;
+               }
+               tc->child = NULL;
+               tc->next = NULL;
+       }
+       talloc_free(null_context);
+       null_context = NULL;
+}
+
+/*
+  enable leak reporting on exit
+*/
+void talloc_enable_leak_report(void)
+{
+       talloc_enable_null_tracking();
+       atexit(talloc_report_null);
+}
+
+/*
+  enable full leak reporting on exit
+*/
+void talloc_enable_leak_report_full(void)
+{
+       talloc_enable_null_tracking();
+       atexit(talloc_report_null_full);
+}
+
+/* 
+   talloc and zero memory. 
+*/
+void *_talloc_zero(const void *ctx, size_t size, const char *name)
+{
+       void *p = _talloc_named_const(ctx, size, name);
+
+       if (p) {
+               memset(p, '\0', size);
+       }
+
+       return p;
+}
+
+/*
+  memdup with a talloc. 
+*/
+void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
+{
+       void *newp = _talloc_named_const(t, size, name);
+
+       if (likely(newp)) {
+               memcpy(newp, p, size);
+       }
+
+       return newp;
+}
+
+static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
+{
+       char *ret;
+
+       ret = (char *)__talloc(t, len + 1);
+       if (unlikely(!ret)) return NULL;
+
+       memcpy(ret, p, len);
+       ret[len] = 0;
+
+       _talloc_set_name_const(ret, ret);
+       return ret;
+}
+
+/*
+  strdup with a talloc
+*/
+char *talloc_strdup(const void *t, const char *p)
+{
+       if (unlikely(!p)) return NULL;
+       return __talloc_strlendup(t, p, strlen(p));
+}
+
+/*
+  strndup with a talloc
+*/
+char *talloc_strndup(const void *t, const char *p, size_t n)
+{
+       if (unlikely(!p)) return NULL;
+       return __talloc_strlendup(t, p, strnlen(p, n));
+}
+
+static inline char *__talloc_strlendup_append(char *s, size_t slen,
+                                             const char *a, size_t alen)
+{
+       char *ret;
+
+       ret = talloc_realloc(NULL, s, char, slen + alen + 1);
+       if (unlikely(!ret)) return NULL;
+
+       /* append the string and the trailing \0 */
+       memcpy(&ret[slen], a, alen);
+       ret[slen+alen] = 0;
+
+       _talloc_set_name_const(ret, ret);
+       return ret;
+}
+
+/*
+ * Appends at the end of the string.
+ */
+char *talloc_strdup_append(char *s, const char *a)
+{
+       if (unlikely(!s)) {
+               return talloc_strdup(NULL, a);
+       }
+
+       if (unlikely(!a)) {
+               return s;
+       }
+
+       return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
+}
+
+/*
+ * Appends at the end of the talloc'ed buffer,
+ * not the end of the string.
+ */
+char *talloc_strdup_append_buffer(char *s, const char *a)
+{
+       size_t slen;
+
+       if (unlikely(!s)) {
+               return talloc_strdup(NULL, a);
+       }
+
+       if (unlikely(!a)) {
+               return s;
+       }
+
+       slen = talloc_get_size(s);
+       if (likely(slen > 0)) {
+               slen--;
+       }
+
+       return __talloc_strlendup_append(s, slen, a, strlen(a));
+}
+
+/*
+ * Appends at the end of the string.
+ */
+char *talloc_strndup_append(char *s, const char *a, size_t n)
+{
+       if (unlikely(!s)) {
+               return talloc_strdup(NULL, a);
+       }
+
+       if (unlikely(!a)) {
+               return s;
+       }
+
+       return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
+}
+
+/*
+ * Appends at the end of the talloc'ed buffer,
+ * not the end of the string.
+ */
+char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
+{
+       size_t slen;
+
+       if (unlikely(!s)) {
+               return talloc_strdup(NULL, a);
+       }
+
+       if (unlikely(!a)) {
+               return s;
+       }
+
+       slen = talloc_get_size(s);
+       if (likely(slen > 0)) {
+               slen--;
+       }
+
+       return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
+}
+
+char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
+{
+       int len;
+       char *ret;
+       va_list ap2;
+       char c;
+
+       /* this call looks strange, but it makes it work on older solaris boxes */
+       va_copy(ap2, ap);
+       len = vsnprintf(&c, 1, fmt, ap2);
+       va_end(ap2);
+       if (unlikely(len < 0)) {
+               return NULL;
+       }
+
+       ret = (char *)__talloc(t, len+1);
+       if (unlikely(!ret)) return NULL;
+
+       va_copy(ap2, ap);
+       vsnprintf(ret, len+1, fmt, ap2);
+       va_end(ap2);
+
+       _talloc_set_name_const(ret, ret);
+       return ret;
+}
+
+
+/*
+  Perform string formatting, and return a pointer to newly allocated
+  memory holding the result, inside a memory pool.
+ */
+char *talloc_asprintf(const void *t, const char *fmt, ...)
+{
+       va_list ap;
+       char *ret;
+
+       va_start(ap, fmt);
+       ret = talloc_vasprintf(t, fmt, ap);
+       va_end(ap);
+       return ret;
+}
+
+static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
+                                                const char *fmt, va_list ap)
+                                                PRINTF_ATTRIBUTE(3,0);
+
+static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
+                                                const char *fmt, va_list ap)
+{
+       ssize_t alen;
+       va_list ap2;
+       char c;
+
+       va_copy(ap2, ap);
+       alen = vsnprintf(&c, 1, fmt, ap2);
+       va_end(ap2);
+
+       if (alen <= 0) {
+               /* Either the vsnprintf failed or the format resulted in
+                * no characters being formatted. In the former case, we
+                * ought to return NULL, in the latter we ought to return
+                * the original string. Most current callers of this
+                * function expect it to never return NULL.
+                */
+               return s;
+       }
+
+       s = talloc_realloc(NULL, s, char, slen + alen + 1);
+       if (!s) return NULL;
+
+       va_copy(ap2, ap);
+       vsnprintf(s + slen, alen + 1, fmt, ap2);
+       va_end(ap2);
+
+       _talloc_set_name_const(s, s);
+       return s;
+}
+
+/**
+ * Realloc @p s to append the formatted result of @p fmt and @p ap,
+ * and return @p s, which may have moved.  Good for gradually
+ * accumulating output into a string buffer. Appends at the end
+ * of the string.
+ **/
+char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
+{
+       if (unlikely(!s)) {
+               return talloc_vasprintf(NULL, fmt, ap);
+       }
+
+       return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
+}
+
+/**
+ * Realloc @p s to append the formatted result of @p fmt and @p ap,
+ * and return @p s, which may have moved. Always appends at the
+ * end of the talloc'ed buffer, not the end of the string.
+ **/
+char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
+{
+       size_t slen;
+
+       if (unlikely(!s)) {
+               return talloc_vasprintf(NULL, fmt, ap);
+       }
+
+       slen = talloc_get_size(s);
+       if (likely(slen > 0)) {
+               slen--;
+       }
+
+       return __talloc_vaslenprintf_append(s, slen, fmt, ap);
+}
+
+/*
+  Realloc @p s to append the formatted result of @p fmt and return @p
+  s, which may have moved.  Good for gradually accumulating output
+  into a string buffer.
+ */
+char *talloc_asprintf_append(char *s, const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       s = talloc_vasprintf_append(s, fmt, ap);
+       va_end(ap);
+       return s;
+}
+
+/*
+  Realloc @p s to append the formatted result of @p fmt and return @p
+  s, which may have moved.  Good for gradually accumulating output
+  into a buffer.
+ */
+char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       s = talloc_vasprintf_append_buffer(s, fmt, ap);
+       va_end(ap);
+       return s;
+}
+
+/*
+  alloc an array, checking for integer overflow in the array size
+*/
+void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
+{
+       if (count >= MAX_TALLOC_SIZE/el_size) {
+               return NULL;
+       }
+       return _talloc_named_const(ctx, el_size * count, name);
+}
+
+/*
+  alloc an zero array, checking for integer overflow in the array size
+*/
+void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
+{
+       if (count >= MAX_TALLOC_SIZE/el_size) {
+               return NULL;
+       }
+       return _talloc_zero(ctx, el_size * count, name);
+}
+
+/*
+  realloc an array, checking for integer overflow in the array size
+*/
+void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
+{
+       if (count >= MAX_TALLOC_SIZE/el_size) {
+               return NULL;
+       }
+       return _talloc_realloc(ctx, ptr, el_size * count, name);
+}
+
+/*
+  a function version of talloc_realloc(), so it can be passed as a function pointer
+  to libraries that want a realloc function (a realloc function encapsulates
+  all the basic capabilities of an allocation library, which is why this is useful)
+*/
+void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
+{
+       return _talloc_realloc(context, ptr, size, NULL);
+}
+
+
+static int talloc_autofree_destructor(void *ptr)
+{
+       autofree_context = NULL;
+       return 0;
+}
+
+static void talloc_autofree(void)
+{
+       talloc_free(autofree_context);
+}
+
+/*
+  return a context which will be auto-freed on exit
+  this is useful for reducing the noise in leak reports
+*/
+void *talloc_autofree_context(void)
+{
+       if (autofree_context == NULL) {
+               autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
+               talloc_set_destructor(autofree_context, talloc_autofree_destructor);
+               atexit(talloc_autofree);
+       }
+       return autofree_context;
+}
+
+size_t talloc_get_size(const void *context)
+{
+       struct talloc_chunk *tc;
+
+       if (context == NULL) {
+               context = null_context;
+       }
+       if (context == NULL) {
+               return 0;
+       }
+
+       tc = talloc_chunk_from_ptr(context);
+
+       return tc->size;
+}
+
+/*
+  find a parent of this context that has the given name, if any
+*/
+void *talloc_find_parent_byname(const void *context, const char *name)
+{
+       struct talloc_chunk *tc;
+
+       if (context == NULL) {
+               return NULL;
+       }
+
+       tc = talloc_chunk_from_ptr(context);
+       while (tc) {
+               if (tc->name && strcmp(tc->name, name) == 0) {
+                       return TC_PTR_FROM_CHUNK(tc);
+               }
+               while (tc && tc->prev) tc = tc->prev;
+               if (tc) {
+                       tc = tc->parent;
+               }
+       }
+       return NULL;
+}
+
+/*
+  show the parentage of a context
+*/
+void talloc_show_parents(const void *context, FILE *file)
+{
+       struct talloc_chunk *tc;
+
+       if (context == NULL) {
+               fprintf(file, "talloc no parents for NULL\n");
+               return;
+       }
+
+       tc = talloc_chunk_from_ptr(context);
+       fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
+       while (tc) {
+               fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
+               while (tc && tc->prev) tc = tc->prev;
+               if (tc) {
+                       tc = tc->parent;
+               }
+       }
+       fflush(file);
+}
+
+/*
+  return 1 if ptr is a parent of context
+*/
+int talloc_is_parent(const void *context, const void *ptr)
+{
+       struct talloc_chunk *tc;
+
+       if (context == NULL) {
+               return 0;
+       }
+
+       tc = talloc_chunk_from_ptr(context);
+       while (tc) {
+               if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
+               while (tc && tc->prev) tc = tc->prev;
+               if (tc) {
+                       tc = tc->parent;
+               }
+       }
+       return 0;
+}
index 98e8ffccd53b28905f752591777d292725dc7ec8..e4f6d2b3b2a86ac698ea38000e23406f0141250b 100644 (file)
@@ -139,13 +139,11 @@ static const char *charset_name(charset_t ch)
     if (!ret)
         ret = charset_names[ch];
 
-#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
+#if defined(CODESET)
     if (ret && strcasecmp(ret, "LOCALE") == 0) {
         const char *ln = NULL;
 
-#ifdef HAVE_SETLOCALE
         setlocale(LC_ALL, "");
-#endif
         ln = nl_langinfo(CODESET);
         if (ln) {
             /* Check whether the charset name is supported
index b844dc5abbd3b87d1d153a99babeb2438e7cf756..0a5ebd68ce08aaae90e4e7abdebc43b59bc8231a 100644 (file)
@@ -18,8 +18,6 @@ libutil_la_SOURCES = \
        server_ipc.c    \
        server_lock.c   \
        socket.c        \
-       strcasestr.c    \
        strdicasecmp.c  \
-       strlcpy.c       \
        volinfo.c \
        unix.c
index 60db65ac9bef53f2eaf5f514fb230b982f869002..48c4fe058d715c094d9e5a9035866eade4d2bf1d 100644 (file)
@@ -36,7 +36,7 @@
 #include <atalk/logger.h>
 
 #ifndef SIGNAL_CAST
-#define SIGNAL_CAST (RETSIGTYPE (*)(int))
+#define SIGNAL_CAST (void (*)(int))
 #endif
 #ifndef SAFE_FREE /* Oh no this is also defined in tdb.h */
 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
diff --git a/libatalk/util/strcasestr.c b/libatalk/util/strcasestr.c
deleted file mode 100644 (file)
index b26c89f..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* Return the offset of one string within another.
-   Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-/*
- * My personal strstr() implementation that beats most other algorithms.
- * Until someone tells me otherwise, I assume that this is the
- * fastest implementation of strstr() in C.
- * I deliberately chose not to comment it.  You should have at least
- * as much fun trying to understand it, as I had to write it :-).
- *
- * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de        */
-/* added strcasestr support, davidm@lineo.com */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#ifndef HAVE_STRCASESTR 
-
-#if  defined HAVE_STRING_H
-# include <string.h>
-#endif
-
-typedef unsigned chartype;
-
-#include <ctype.h>
-#define VAL(x) tolower(x)
-#define FUNC strcasestr
-#undef strcasestr
-
-char * FUNC ( const char *phaystack, const char *pneedle)
-{
-       register const unsigned char *haystack, *needle;
-       register chartype b, c;
-
-       haystack = (const unsigned char *) phaystack;
-       needle = (const unsigned char *) pneedle;
-
-       b = *needle;
-       if (b != '\0') {
-               haystack--;                             /* possible ANSI violation */
-               do {
-                       c = *++haystack;
-                       if (c == '\0')
-                               goto ret0;
-               }
-               while (VAL(c) != VAL(b));
-
-               c = *++needle;
-               if (c == '\0')
-                       goto foundneedle;
-               ++needle;
-               goto jin;
-
-               for (;;) {
-                       register chartype a;
-                       register const unsigned char *rhaystack, *rneedle;
-
-                       do {
-                               a = *++haystack;
-                               if (a == '\0')
-                                       goto ret0;
-                               if (VAL(a) == VAL(b))
-                                       break;
-                               a = *++haystack;
-                               if (a == '\0')
-                                       goto ret0;
-                 shloop:;}
-                       while (VAL(a) != VAL(b));
-
-                 jin:a = *++haystack;
-                       if (a == '\0')
-                               goto ret0;
-
-                       if (VAL(a) != VAL(c))
-                               goto shloop;
-
-                       rhaystack = haystack-- + 1;
-                       rneedle = needle;
-                       a = *rneedle;
-
-                       if (VAL(*rhaystack) == VAL(a))
-                               do {
-                                       if (a == '\0')
-                                               goto foundneedle;
-                                       ++rhaystack;
-                                       a = *++needle;
-                                       if (VAL(*rhaystack) != VAL(a))
-                                               break;
-                                       if (a == '\0')
-                                               goto foundneedle;
-                                       ++rhaystack;
-                                       a = *++needle;
-                               }
-                               while (VAL(*rhaystack) == VAL(a));
-
-                       needle = rneedle;       /* took the register-poor approach */
-
-                       if (a == '\0')
-                               break;
-               }
-       }
-  foundneedle:
-       return (char *) haystack;
-  ret0:
-       return 0;
-}
-#endif
diff --git a/libatalk/util/strlcpy.c b/libatalk/util/strlcpy.c
deleted file mode 100644 (file)
index 314b039..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-   Copy from samba lib/replace.c
-
-   Unix SMB/CIFS implementation.
-   replacement routines for broken systems
-   Copyright (C) Andrew Tridgell 1992-1998
-   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., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-   strlcpy strlcat functions.
-*/
-                          
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <atalk/util.h>
-#include <string.h>
-
-#ifndef HAVE_STRLCPY
-/* like strncpy but does not 0 fill the buffer and always null
-   terminates. bufsize is the size of the destination buffer */
- size_t strlcpy(char *d, const char *s, size_t bufsize)
-{
-        size_t len = strlen(s);
-        size_t ret = len;
-
-        if (bufsize <= 0) 
-               return 0;
-
-        if (len >= bufsize) 
-               len = bufsize-1;
-
-        memcpy(d, s, len);
-        d[len] = 0;
-        return ret;
-}
-#endif
-#ifndef HAVE_STRLCAT
-/* like strncat but does not 0 fill the buffer and always null
-   terminates. bufsize is the length of the buffer, which should
-   be one more than the maximum resulting string length */
- size_t strlcat(char *d, const char *s, size_t bufsize)
-{
-        size_t len1 = strlen(d);
-        size_t len2 = strlen(s);
-        size_t ret = len1 + len2;
-
-       if (len1 >= bufsize) {
-               return 0;
-       } 
-        if (len1+len2 >= bufsize) {
-                len2 = bufsize - (len1+1);
-        }
-        if (len2 > 0) {
-                memcpy(d+len1, s, len2);
-                d[len1+len2] = 0;
-        }
-        return ret;
-}
-#endif