[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Fri Jun 1 20:01:03 MDT 2012


The branch, master has been updated
       via  81a754f lib/replace: Relicence xattr.c to LGPLv3
       via  2716b0a build: Always attempt to build posix ACLs
       via  e9d797e lib/replace: Merge remaining xattr test details from lib/util
       via  f9b7cd5 s4-xattr: Use libreplace xattr functions directly
       via  c290cdb lib/replace: xattr wrappers in lib/replace rather than source3/lib/system.c
       via  664af06 lib/replace: We cannot use strchr_m in lib/replace
       via  954da1b lib/replace: DEBUG is not acceptable here, as this may not be linked into Samba
       via  b347067 lib/replace: Copy lib/system.c xattr wrappers to lib/replace
      from  97a4901 s3: Same fix as 8576256, this time for fgetxattr

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 81a754fb6462bc9f6b4be6bc1ee04a85a85e1686
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat Jun 2 09:28:04 2012 +1000

    lib/replace: Relicence xattr.c to LGPLv3
    
    By the kind consent of the copyright holders.  (There wasn't any code from tridge
    in the code brought in from source3/lib/system.c).
    
    Andrew Bartlett
    
    Autobuild-User: Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date: Sat Jun  2 04:00:42 CEST 2012 on sn-devel-104

commit 2716b0a3f3037a5b8ac95b586158ed849c3418c3
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jun 1 15:24:20 2012 +1000

    build: Always attempt to build posix ACLs
    
    These are on more systems than just linux.  If the configure test passes
    then assume it is available.
    
    Andrew Bartlett

commit e9d797e153ae95561dbb10b56a41281b2472f137
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jun 1 15:01:09 2012 +1000

    lib/replace: Merge remaining xattr test details from lib/util
    
    I prefer the longer XATTR_ADDITIONAL_OPTIONS define and the NULL
    rather than 0 values in the getxattr test.
    
    Andrew Bartlett

commit f9b7cd53b9fe253b122cb545c2dd1be073ab0592
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jun 1 13:41:46 2012 +1000

    s4-xattr: Use libreplace xattr functions directly

commit c290cdb9349220ba70b54143e1432da0230e2cee
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jun 1 13:29:38 2012 +1000

    lib/replace: xattr wrappers in lib/replace rather than source3/lib/system.c
    
    This also moves all the still-used configure tests etc.  The unused OSF API
    is also removed at this time.
    
    Andrew Bartlett

commit 664af060ac9ea83b565fbb817bb63d67d83843ef
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jun 1 14:07:42 2012 +1000

    lib/replace: We cannot use strchr_m in lib/replace
    
    In any case, it is always safe to search for . even in a multibyte string.
    
    Andrew Bartlett

commit 954da1b81ec1a4ef9b417885e3a587b9c49b7056
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jun 1 14:05:10 2012 +1000

    lib/replace: DEBUG is not acceptable here, as this may not be linked into Samba

commit b347067a67b791fa83c1cfa5b33a5de1a3045170
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jun 1 14:14:45 2012 +1000

    lib/replace: Copy lib/system.c xattr wrappers to lib/replace

-----------------------------------------------------------------------

Summary of changes:
 lib/replace/libreplace.m4                   |   47 ++
 lib/replace/replace.h                       |   40 ++
 lib/replace/system/filesys.h                |   56 +++
 lib/replace/wscript                         |   38 ++-
 lib/replace/xattr.c                         |  699 +++++++++++++++++++++++++++
 lib/util/wrap_xattr.c                       |  120 -----
 lib/util/wrap_xattr.h                       |   33 --
 lib/util/wscript_build                      |    9 -
 lib/util/wscript_configure                  |   13 -
 source3/configure.in                        |   59 ---
 source3/include/includes.h                  |   23 -
 source3/lib/system.c                        |  678 --------------------------
 source3/modules/vfs_default.c               |   16 +-
 source3/wscript                             |   44 +--
 source4/ntvfs/posix/python/pyposix_eadb.c   |    1 -
 source4/ntvfs/posix/python/pyxattr_native.c |    8 +-
 source4/ntvfs/posix/python/pyxattr_tdb.c    |    1 -
 source4/ntvfs/posix/wscript_build           |    4 +-
 source4/ntvfs/posix/xattr_system.c          |   13 +-
 19 files changed, 913 insertions(+), 989 deletions(-)
 create mode 100644 lib/replace/xattr.c
 delete mode 100644 lib/util/wrap_xattr.c
 delete mode 100644 lib/util/wrap_xattr.h


Changeset truncated at 500 lines:

diff --git a/lib/replace/libreplace.m4 b/lib/replace/libreplace.m4
index 7335c98..641d25b 100644
--- a/lib/replace/libreplace.m4
+++ b/lib/replace/libreplace.m4
@@ -144,6 +144,53 @@ AC_CHECK_FUNCS(clock_gettime,libreplace_cv_have_clock_gettime=yes,[
 		libreplace_cv_have_clock_gettime=yes
 		AC_DEFINE(HAVE_CLOCK_GETTIME, 1, Define to 1 if there is support for clock_gettime)])
 ])
+
+AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h sys/extattr.h sys/uio.h)
+AC_CHECK_HEADERS(sys/ea.h sys/proplist.h)
+
+############################################
+# Check for EA implementations
+case "$host_os" in
+  *freebsd4* | *dragonfly* )
+	AC_DEFINE(BROKEN_EXTATTR, 1, [Does extattr API work])
+  ;;
+  *)
+	AC_SEARCH_LIBS(getxattr, [attr])
+	AC_CHECK_FUNCS(attr_get attr_getf attr_list attr_listf attropen attr_remove)
+	AC_CHECK_FUNCS(attr_removef attr_set attr_setf extattr_delete_fd extattr_delete_file)
+	AC_CHECK_FUNCS(extattr_get_fd extattr_get_file extattr_list_fd extattr_list_file)
+	AC_CHECK_FUNCS(extattr_set_fd extattr_set_file fgetea fgetxattr flistea flistxattr)
+	AC_CHECK_FUNCS(fremoveea fremovexattr fsetea fsetxattr getea getxattr listea)
+	AC_CHECK_FUNCS(listxattr removeea removexattr setea setxattr)
+
+  ;;
+esac
+
+
+########################################################
+# Do xattr functions take additional options like on Darwin?
+if test x"$ac_cv_func_getxattr" = x"yes" ; then
+	AC_CACHE_CHECK([whether xattr interface takes additional options], smb_attr_cv_xattr_add_opt, [
+		old_LIBS=$LIBS
+		LIBS="$LIBS $ACL_LIBS"
+		AC_TRY_COMPILE([
+			#include <sys/types.h>
+			#if HAVE_ATTR_XATTR_H
+			#include <attr/xattr.h>
+			#elif HAVE_SYS_XATTR_H
+			#include <sys/xattr.h>
+			#endif
+		],[
+			getxattr(NULL, NULL, NULL, 0, 0, 0);
+		],
+	        [smb_attr_cv_xattr_add_opt=yes],
+		[smb_attr_cv_xattr_add_opt=no;LIBS=$old_LIBS])
+	])
+	if test x"$smb_attr_cv_xattr_add_opt" = x"yes"; then
+		AC_DEFINE(XATTR_ADDITIONAL_OPTIONS, 1, [xattr functions have additional options])
+	fi
+fi
+
 AC_CHECK_FUNCS(get_current_dir_name)
 AC_HAVE_DECL(setresuid, [#include <unistd.h>])
 AC_HAVE_DECL(setresgid, [#include <unistd.h>])
diff --git a/lib/replace/replace.h b/lib/replace/replace.h
index 776da8a..218303f 100644
--- a/lib/replace/replace.h
+++ b/lib/replace/replace.h
@@ -543,6 +543,46 @@ ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset)
 /* prototype is in "system/network.h" */
 #endif
 
+#if !defined(HAVE_GETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+#define getxattr rep_getxattr
+/* prototype is in "system/filesys.h" */
+#endif
+
+#if !defined(HAVE_FGETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+#define fgetxattr rep_fgetxattr
+/* prototype is in "system/filesys.h" */
+#endif
+
+#if !defined(HAVE_LISTXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+#define listxattr rep_listxattr
+/* prototype is in "system/filesys.h" */
+#endif
+
+#if !defined(HAVE_FLISTXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+#define flistxattr rep_flistxattr
+/* prototype is in "system/filesys.h" */
+#endif
+
+#if !defined(HAVE_REMOVEXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+#define removexattr rep_removexattr
+/* prototype is in "system/filesys.h" */
+#endif
+
+#if !defined(HAVE_FREMOVEXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+#define fremovexattr rep_fremovexattr
+/* prototype is in "system/filesys.h" */
+#endif
+
+#if !defined(HAVE_SETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+#define setxattr rep_setxattr
+/* prototype is in "system/filesys.h" */
+#endif
+
+#if !defined(HAVE_FSETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+#define fsetxattr rep_fsetxattr
+/* prototype is in "system/filesys.h" */
+#endif
+
 #ifndef HAVE_GET_CURRENT_DIR_NAME
 #define get_current_dir_name rep_get_current_dir_name
 char *rep_get_current_dir_name(void);
diff --git a/lib/replace/system/filesys.h b/lib/replace/system/filesys.h
index 2393068..a72a59a 100644
--- a/lib/replace/system/filesys.h
+++ b/lib/replace/system/filesys.h
@@ -123,11 +123,26 @@
 #include <sys/xattr.h>
 #endif
 
+#ifdef HAVE_SYS_EA_H
+#include <sys/ea.h>
+#endif
+
+#ifdef HAVE_SYS_EXTATTR_H
+#include <sys/extattr.h>
+#endif
 
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
 #endif
 
+#ifndef XATTR_CREATE
+#define XATTR_CREATE  0x1       /* set value, fail if attr already exists */
+#endif
+
+#ifndef XATTR_REPLACE
+#define XATTR_REPLACE 0x2       /* set value, fail if attr does not exist */
+#endif
+
 /* Some POSIX definitions for those without */
 
 #ifndef S_IFDIR
@@ -208,4 +223,45 @@
 #define ENOATTR ENODATA
 #endif
 
+
+#if !defined(HAVE_GETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t size);
+/* define is in "replace.h" */
+#endif
+
+#if !defined(HAVE_FGETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size);
+/* define is in "replace.h" */
+#endif
+
+#if !defined(HAVE_LISTXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+ssize_t rep_listxattr (const char *path, char *list, size_t size);
+/* define is in "replace.h" */
+#endif
+
+#if !defined(HAVE_FLISTXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+ssize_t rep_flistxattr (int filedes, char *list, size_t size);
+/* define is in "replace.h" */
+#endif
+
+#if !defined(HAVE_REMOVEXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+int rep_removexattr (const char *path, const char *name);
+/* define is in "replace.h" */
+#endif
+
+#if !defined(HAVE_FREMOVEXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+int rep_fremovexattr (int filedes, const char *name);
+/* define is in "replace.h" */
+#endif
+
+#if !defined(HAVE_SETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+int rep_setxattr (const char *path, const char *name, const void *value, size_t size, int flags);
+/* define is in "replace.h" */
+#endif
+
+#if !defined(HAVE_FSETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS)
+int rep_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags);
+/* define is in "replace.h" */
+#endif
+
 #endif
diff --git a/lib/replace/wscript b/lib/replace/wscript
index d7b0634..6331b88 100644
--- a/lib/replace/wscript
+++ b/lib/replace/wscript
@@ -211,6 +211,40 @@ def configure(conf):
     conf.CHECK_FUNCS('getgrent_r getgrgid_r getgrnam_r getgrouplist getpagesize')
     conf.CHECK_FUNCS('getpwent_r getpwnam_r getpwuid_r epoll_create')
 
+    conf.SET_TARGET_TYPE('attr', 'EMPTY')
+
+    xattr_headers='sys/attributes.h attr/xattr.h sys/xattr.h'
+
+    conf.CHECK_FUNCS_IN('''
+fgetxattr flistea flistxattr
+fremovexattr fsetxattr getxattr
+listxattr removexattr setxattr
+''', 'attr', checklibc=True, headers=xattr_headers)
+
+    # We need to check for linux xattrs first, as we do not wish to link to -lattr
+    # (the XFS compat API) on Linux systems with the native xattr API
+    if not conf.CONFIG_SET('HAVE_GETXATTR'):
+        conf.CHECK_FUNCS_IN('''
+attr_get attr_getf attr_list attr_listf attropen attr_remove
+attr_removef attr_set attr_setf extattr_delete_fd extattr_delete_file
+extattr_get_fd extattr_get_file extattr_list_fd extattr_list_file
+extattr_set_fd extattr_set_file fgetea flistea
+fremoveea fsetea getea listea
+removeea setea
+''', 'attr', checklibc=True, headers=xattr_headers)
+
+    if (conf.CONFIG_SET('HAVE_ATTR_LISTF') or
+        conf.CONFIG_SET('HAVE_EXTATTR_LIST_FD') or
+        conf.CONFIG_SET('HAVE_FLISTEA') or
+        conf.CONFIG_SET('HAVE_FLISTXATTR')):
+            conf.DEFINE('HAVE_XATTR_SUPPORT', 1)
+
+    # Darwin has extra options to xattr-family functions
+    conf.CHECK_CODE('getxattr(NULL, NULL, NULL, 0, 0, 0)',
+                    headers=xattr_headers, local_include=False,
+                    define='XATTR_ADDITIONAL_OPTIONS',
+                    msg="Checking whether xattr interface takes additional options")
+
     conf.CHECK_FUNCS_IN('dlopen dlsym dlerror dlclose', 'dl',
                         checklibc=True, headers='dlfcn.h dl.h')
 
@@ -474,6 +508,8 @@ def build(bld):
     if not bld.CONFIG_SET('HAVE_INET_ATON'):     REPLACE_SOURCE += ' inet_aton.c'
     if not bld.CONFIG_SET('HAVE_INET_NTOP'):     REPLACE_SOURCE += ' inet_ntop.c'
     if not bld.CONFIG_SET('HAVE_INET_PTON'):     REPLACE_SOURCE += ' inet_pton.c'
+    if not bld.CONFIG_SET('HAVE_GETXATTR') or bld.CONFIG_SET('XATTR_ADD_OPT'):
+                                                 REPLACE_SOURCE += ' xattr.c'
 
     bld.SAMBA_LIBRARY('replace',
                       source=REPLACE_SOURCE,
@@ -484,7 +520,7 @@ def build(bld):
                       # at the moment:
                       # hide_symbols=bld.BUILTIN_LIBRARY('replace'),
                       private_library=True,
-                      deps='crypt dl nsl socket rt' + extra_libs)
+                      deps='crypt dl nsl socket rt attr' + extra_libs)
 
     bld.SAMBA_SUBSYSTEM('replace-test',
                       source='''test/testsuite.c test/strptime.c
diff --git a/lib/replace/xattr.c b/lib/replace/xattr.c
new file mode 100644
index 0000000..95bea77
--- /dev/null
+++ b/lib/replace/xattr.c
@@ -0,0 +1,699 @@
+/* 
+   Unix SMB/CIFS implementation.
+   replacement routines for xattr implementations
+   Copyright (C) Jeremy Allison  1998-2005
+   Copyright (C) Timur Bakeyev        2005
+   Copyright (C) Bjoern Jacke    2006-2007
+
+     ** NOTE! The following LGPL license applies to the replace
+     ** 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 "replace.h"
+#include "system/filesys.h"
+
+/******** Solaris EA helper function prototypes ********/
+#ifdef HAVE_ATTROPEN
+#define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
+static int solaris_write_xattr(int attrfd, const char *value, size_t size);
+static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size);
+static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size);
+static int solaris_unlinkat(int attrdirfd, const char *name);
+static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode);
+static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode);
+#endif
+
+/**************************************************************************
+ Wrappers for extented attribute calls. Based on the Linux package with
+ support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
+****************************************************************************/
+
+ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t size)
+{
+#if defined(HAVE_GETXATTR)
+#ifndef XATTR_ADDITIONAL_OPTIONS
+	return getxattr(path, name, value, size);
+#else
+	int options = 0;
+	return getxattr(path, name, value, size, 0, options);
+#endif
+#elif defined(HAVE_GETEA)
+	return getea(path, name, value, size);
+#elif defined(HAVE_EXTATTR_GET_FILE)
+	char *s;
+	ssize_t retval;
+	int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
+		EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+	const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
+	/*
+	 * The BSD implementation has a nasty habit of silently truncating
+	 * the returned value to the size of the buffer, so we have to check
+	 * that the buffer is large enough to fit the returned value.
+	 */
+	if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) {
+		if(retval > size) {
+			errno = ERANGE;
+			return -1;
+		}
+		if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0)
+			return retval;
+	}
+
+	return -1;
+#elif defined(HAVE_ATTR_GET)
+	int retval, flags = 0;
+	int valuelength = (int)size;
+	char *attrname = strchr(name,'.') + 1;
+
+	if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
+
+	retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
+
+	return retval ? retval : valuelength;
+#elif defined(HAVE_ATTROPEN)
+	ssize_t ret = -1;
+	int attrfd = solaris_attropen(path, name, O_RDONLY, 0);
+	if (attrfd >= 0) {
+		ret = solaris_read_xattr(attrfd, value, size);
+		close(attrfd);
+	}
+	return ret;
+#else
+	errno = ENOSYS;
+	return -1;
+#endif
+}
+
+ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size)
+{
+#if defined(HAVE_FGETXATTR)
+#ifndef XATTR_ADDITIONAL_OPTIONS
+	return fgetxattr(filedes, name, value, size);
+#else
+	int options = 0;
+	return fgetxattr(filedes, name, value, size, 0, options);
+#endif
+#elif defined(HAVE_FGETEA)
+	return fgetea(filedes, name, value, size);
+#elif defined(HAVE_EXTATTR_GET_FD)
+	char *s;
+	ssize_t retval;
+	int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
+		EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+	const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
+
+	if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) {
+		if(retval > size) {
+			errno = ERANGE;
+			return -1;
+		}
+		if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0)
+			return retval;
+	}
+
+	return -1;
+#elif defined(HAVE_ATTR_GETF)
+	int retval, flags = 0;
+	int valuelength = (int)size;
+	char *attrname = strchr(name,'.') + 1;
+
+	if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
+
+	retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
+
+	return retval ? retval : valuelength;
+#elif defined(HAVE_ATTROPEN)
+	ssize_t ret = -1;
+	int attrfd = solaris_openat(filedes, name, O_RDONLY|O_XATTR, 0);
+	if (attrfd >= 0) {
+		ret = solaris_read_xattr(attrfd, value, size);
+		close(attrfd);
+	}
+	return ret;
+#else
+	errno = ENOSYS;
+	return -1;
+#endif
+}
+
+#if defined(HAVE_EXTATTR_LIST_FILE)
+
+#define EXTATTR_PREFIX(s)	(s), (sizeof((s))-1)
+
+static struct {
+        int space;
+	const char *name;
+	size_t len;
+} 
+extattr[] = {
+	{ EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") },
+        { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") },
+};
+
+typedef union {
+	const char *path;
+	int filedes;
+} extattr_arg;
+
+static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
+{
+	ssize_t list_size, total_size = 0;
+	int i, t, len;
+	char *buf;
+	/* Iterate through extattr(2) namespaces */
+	for(t = 0; t < ARRAY_SIZE(extattr); t++) {
+		switch(type) {
+#if defined(HAVE_EXTATTR_LIST_FILE)
+			case 0:
+				list_size = extattr_list_file(arg.path, extattr[t].space, list, size);
+				break;
+#endif
+#if defined(HAVE_EXTATTR_LIST_LINK)
+			case 1:
+				list_size = extattr_list_link(arg.path, extattr[t].space, list, size);
+				break;
+#endif
+#if defined(HAVE_EXTATTR_LIST_FD)
+			case 2:
+				list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size);
+				break;
+#endif
+			default:
+				errno = ENOSYS;
+				return -1;
+		}
+		/* Some error happend. Errno should be set by the previous call */
+		if(list_size < 0)
+			return -1;
+		/* No attributes */
+		if(list_size == 0)
+			continue;
+		/* XXX: Call with an empty buffer may be used to calculate
+		   necessary buffer size. Unfortunately, we can't say, how
+		   many attributes were returned, so here is the potential
+		   problem with the emulation.
+		*/
+		if(list == NULL) {
+			/* Take the worse case of one char attribute names - 
+			   two bytes per name plus one more for sanity.
+			*/
+			total_size += list_size + (list_size/2 + 1)*extattr[t].len;
+			continue;
+		}
+		/* Count necessary offset to fit namespace prefixes */
+		len = 0;
+		for(i = 0; i < list_size; i += list[i] + 1)
+			len += extattr[t].len;
+
+		total_size += list_size + len;
+		/* Buffer is too small to fit the results */
+		if(total_size > size) {
+			errno = ERANGE;
+			return -1;
+		}
+		/* Shift results back, so we can prepend prefixes */
+		buf = (char *)memmove(list + len, list, list_size);
+
+		for(i = 0; i < list_size; i += len + 1) {
+			len = buf[i];
+			strncpy(list, extattr[t].name, extattr[t].len + 1);
+			list += extattr[t].len;
+			strncpy(list, buf + i + 1, len);
+			list[len] = '\0';
+			list += len + 1;
+		}
+		size -= total_size;
+	}
+	return total_size;
+}
+
+#endif
+


-- 
Samba Shared Repository


More information about the samba-cvs mailing list