lib/replace: Return size of xattr if size argument is 0
[obnox/samba/samba-obnox.git] / lib / replace / xattr.c
index 39f55c66b219ec874146fd0cec13806358ab0fa3..a26ff674a13824bd9948a8949dc79e0e28905c60 100644 (file)
@@ -1,27 +1,33 @@
 /* 
    Unix SMB/CIFS implementation.
-   Samba system utilities
-   Copyright (C) Andrew Tridgell 1992-1998
+   replacement routines for xattr implementations
    Copyright (C) Jeremy Allison  1998-2005
    Copyright (C) Timur Bakeyev        2005
    Copyright (C) Bjoern Jacke    2006-2007
-
-   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 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
+   Copyright (C) Herb Lewis           2003
+   Copyright (C) Andrew Bartlett      2012
+
+     ** 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 General Public License for more details.
+   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 General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+   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"
+#include "system/dir.h"
 
 /******** Solaris EA helper function prototypes ********/
 #ifdef HAVE_ATTROPEN
@@ -45,6 +51,9 @@ ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t si
 #ifndef XATTR_ADDITIONAL_OPTIONS
        return getxattr(path, name, value, size);
 #else
+
+/* So that we do not recursivly call this function */
+#undef getxattr
        int options = 0;
        return getxattr(path, name, value, size, 0, options);
 #endif
@@ -62,7 +71,9 @@ ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t si
         * 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) {
+               if (size == 0) {
+                       return retval;
+               } else if (retval > size) {
                        errno = ERANGE;
                        return -1;
                }
@@ -79,6 +90,9 @@ ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t si
        if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
 
        retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
+       if (size == 0 && retval == -1 && errno == E2BIG) {
+               return valuelength;
+       }
 
        return retval ? retval : valuelength;
 #elif defined(HAVE_ATTROPEN)
@@ -101,6 +115,9 @@ ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size)
 #ifndef XATTR_ADDITIONAL_OPTIONS
        return fgetxattr(filedes, name, value, size);
 #else
+
+/* So that we do not recursivly call this function */
+#undef fgetxattr
        int options = 0;
        return fgetxattr(filedes, name, value, size, 0, options);
 #endif
@@ -114,7 +131,9 @@ ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size)
        const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
 
        if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) {
-               if(retval > size) {
+               if (size == 0) {
+                       return retval;
+               } else if (retval > size) {
                        errno = ERANGE;
                        return -1;
                }
@@ -131,7 +150,9 @@ ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size)
        if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
 
        retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
-
+       if (size == 0 && retval == -1 && errno == E2BIG) {
+               return valuelength;
+       }
        return retval ? retval : valuelength;
 #elif defined(HAVE_ATTROPEN)
        ssize_t ret = -1;
@@ -240,7 +261,7 @@ static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size
 
 #endif
 
-#if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
+#if defined(HAVE_ATTR_LIST) && (defined(HAVE_SYS_ATTRIBUTES_H) || defined(HAVE_ATTR_ATTRIBUTES_H))
 static char attr_buffer[ATTR_MAX_VALUELEN];
 
 static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
@@ -253,7 +274,7 @@ static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t
        size_t ent_size, left = size;
        char *bp = list;
 
-       while (True) {
+       while (true) {
            if (filedes)
                retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
            else
@@ -279,7 +300,7 @@ static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t
        if (retval == 0) {
            flags |= ATTR_ROOT;
            cursor = 0;
-           while (True) {
+           while (true) {
                if (filedes)
                    retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
                else
@@ -314,6 +335,8 @@ ssize_t rep_listxattr (const char *path, char *list, size_t size)
 #ifndef XATTR_ADDITIONAL_OPTIONS
        return listxattr(path, list, size);
 #else
+/* So that we do not recursivly call this function */
+#undef listxattr
        int options = 0;
        return listxattr(path, list, size, options);
 #endif
@@ -345,6 +368,8 @@ ssize_t rep_flistxattr (int filedes, char *list, size_t size)
 #ifndef XATTR_ADDITIONAL_OPTIONS
        return flistxattr(filedes, list, size);
 #else
+/* So that we do not recursivly call this function */
+#undef flistxattr
        int options = 0;
        return flistxattr(filedes, list, size, options);
 #endif
@@ -376,6 +401,8 @@ int rep_removexattr (const char *path, const char *name)
 #ifndef XATTR_ADDITIONAL_OPTIONS
        return removexattr(path, name);
 #else
+/* So that we do not recursivly call this function */
+#undef removexattr
        int options = 0;
        return removexattr(path, name, options);
 #endif
@@ -415,6 +442,8 @@ int rep_fremovexattr (int filedes, const char *name)
 #ifndef XATTR_ADDITIONAL_OPTIONS
        return fremovexattr(filedes, name);
 #else
+/* So that we do not recursivly call this function */
+#undef fremovexattr
        int options = 0;
        return fremovexattr(filedes, name, options);
 #endif
@@ -454,6 +483,8 @@ int rep_setxattr (const char *path, const char *name, const void *value, size_t
 #ifndef XATTR_ADDITIONAL_OPTIONS
        return setxattr(path, name, value, size, flags);
 #else
+/* So that we do not recursivly call this function */
+#undef setxattr
        int options = 0;
        return setxattr(path, name, value, size, 0, options);
 #endif
@@ -519,6 +550,8 @@ int rep_fsetxattr (int filedes, const char *name, const void *value, size_t size
 #ifndef XATTR_ADDITIONAL_OPTIONS
        return fsetxattr(filedes, name, value, size, flags);
 #else
+/* So that we do not recursivly call this function */
+#undef fsetxattr
        int options = 0;
        return fsetxattr(filedes, name, value, size, 0, options);
 #endif