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 <abart...@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 <abart...@samba.org>
    Autobuild-Date: Sat Jun  2 04:00:42 CEST 2012 on sn-devel-104

commit 2716b0a3f3037a5b8ac95b586158ed849c3418c3
Author: Andrew Bartlett <abart...@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 <abart...@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 <abart...@samba.org>
Date:   Fri Jun 1 13:41:46 2012 +1000

    s4-xattr: Use libreplace xattr functions directly

commit c290cdb9349220ba70b54143e1432da0230e2cee
Author: Andrew Bartlett <abart...@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 <abart...@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 <abart...@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 <abart...@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

Reply via email to